node
what
是一个javascript运行时环境
- 简单点讲就是Node.js可以解析和执行javascript代码
- 以前只有浏览器可以解析执行javascript代码
- 也就是说现在的javascript可以完全脱离浏览器来运行,一切都归功于Node.js
- chrome V8 runtime
- 事件驱动*
- 非阻塞的I/O *
I/O : input output 输入输出流 正常下I/O的操作都是阻塞的(ajax 同步)
网格请求 数据库处理 文件的读写 , (非阻塞)
优点: 高并发特别好
why为什么学
- 防止甩锅 明确数据交互的错误问题在谁 具有服务端开发经验更好
- 能够书写API 斜杠青年
- 了解前后端的交互流程 front-end back-end
- 全干
api 接口文档
js运行环境
- 浏览器
- 基本语法
- bom
- dom
- ajax
- 系统文件数据库(不能,不是语言不能,安全性考虑不能操作)
+服务器 - 基本语法
- 能操作数据库
- 能操作本地文件
限制语言能力的不是语言本身,而是语言的运行环境(平台)
nvm 版本管理工具
简单的http服务
代码:
var http = require('http');
//1.创建Server
var server=http.createServer();
//2.监听request请求事件,设置请求处理函数
server.on('request',function (req,res) {
console.log('收到请求了,请求路径是:'+req.url);
// res.end('Hello world!');
//根据不同的请求路径发送不同的响应结果
//1.获取请求路径
//res.url获取到的是端口号之后的那一部分路径
//也就是说所有的url都是以/开头的
//2.判断路径处理响应
var url=req.url;
if (url=='/') {
res.end('index page');
}else if(url=='/login'){
res.end('login page');
}else{
res.end('404 Not Found.');
}
})
可以响应数组,但要转化
var http = require('http');
//1.创建Server
var server=http.createServer();
//2.监听request请求事件,设置请求处理函数
server.on('request',function (req,res) {
console.log('收到请求了,请求路径是:'+req.url);
// res.end('Hello world!');
//根据不同的请求路径发送不同的响应结果
//1.获取请求路径
//res.url获取到的是端口号之后的那一部分路径
//也就是说所有的url都是以/开头的
//2.判断路径处理响应
var url=req.url;
// if (url=='/') {
// res.end('index page');
// }else if(url=='/login'){
// res.end('login page');
// }else{
// res.end('404 Not Found.');
// }
if (url==='/products') {
var products=[
{
name:'苹果X',
price:8888
},
{
name:'菠萝X',
price:2888
},
{
name:'小辣椒X',
price:1888
}
];
//响应内容只能是二进制数据或者是字符串
res.end(JSON.stringify(products)); //转化为字符串
}
})
//3.绑定端口号,启动服务
server.listen(3000,function(){
console.log('服务启动成功,可以访问了...');
})
3.Node中的JavaScript
- EcmaScript
- 没有DOM,BOM
- 核心模块
- 第三方模块
- 用户自定义模块
3.1 核心模块
Node为JavaScript提供了很多服务器级别的API
- 文件操作的fs核心模块
- http构建的http模块
- path路径操作模块
- os操作模块
- …
3.2
以后只要说这个模块是一个核心模块,必须手动先使用require
方法来加载,然后才能使用
var fs=require('fs'); //参数不能乱写
var http=require('http');
3.3 用户自定义模块
- require
require是一个方法
它的作用是用来加载模块的
相对路径必须加./
可以省略后缀名
相对路径中的 ./ 不能省略,否则报错
- 模块系统
- 在node中,没有全局作用域,只有模块作用域
- 在node中,只能通过require方法来加载执行多个javascript文件
- require加载只能是执行其中的代码,文件与文件之间由于是模块作用域,所以不会有污染的问题
- 模块完全是封闭的
- 外部无法访问内部
- 内部也无法访问外部
require 方法有两个作用:
- 加载文件模块并执行里面的代码
- 拿到被加载文件模块导出的接口对象
既然是模块作用域,那如何让模块与模块之间进行通信呢?
有时候,我们加载文件模块的目的不是为了简简单单的执行里面的代码,更重要的是为了使用里面的内容
- 每个文 件模块中都提供了一个对象 :exports
- exports默认是一个空对象
- 你要做的就是把所有需要被外部访问的成员手动的挂载到
exports
接口对象中 - 然后谁来’require’这个模块,谁就可以得到模块内部
exports
接口对象
案例
a.js
var fs=require('fs')
console.log(ret.foo);
console.log(ret.add(1110,30));
ret.readFile('./a.js')
fs.readFile('./a.js',function (err,data) {
if (err) {
console.log('读取文件失败')
}else{
console.log(data.toString())
}
})
b.js
exports.foo='hello'
// console.log(exports);
exports.add=function (x,y) {
return x+y;
}
exports.readFile=function (path,callback) {
console.log('文件路径:',path)
}
Node 在Vscode中要调试可下载插件,然后修改laungch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
~~// "program": "${file}/a.js"~~ //原始是这样的
"program": "${workspaceRoot}/加载与导出/a.js" //要改成这样才能运行
}
]
}
3.4 第三方模块
4.WEB服务器开发
4.1 ip地址和端口号
- IP地址用来定位计算机
- 端口号用来定位具体的应用程序
(所有需要联网通信的软件必须具有端口号) - 端口号的范围从0-65536之间
- 在计算机中有一些默认端口号,最好不要去使用 ,如80
- 可以同时开启多个服务,但一定要确保占用的端口号不一致
//require
var http = require('http')
// 1. 创建Server
var server = http.createServer()
// 2. 监听Server的request请求事件,设置请求处理函数
server.on('request',function (req,res) {
//在服务端默认发送的数据,其实是utf8编码的内容
//但是浏览器不知道你是utf8编码的内容
//解决方法就是告诉浏览器我给你发送的编码是什么
//在http协议中,Content-Type就是用来告知对方我给你发送的数据内容是什么
res.setHeader('Content-type','text/plain;charset=utf-8')
res.end('hello 世界')
})
// 3. 绑定端口号,启动服务
server.listen(3000,function (params) {
console.log('Server is Running...')
})
node报错
node 报错 throw er;//unhandled ‘error’ event
端口被占用. 找到端口号所对应的pid ,直接干掉就行了
- netstat -ano|findstr “3000”
- taskkill -PID 13512 -F
Content-Type
- 服务器最好把每次响应的数据是什么内容类型都 告诉客户端
- 不同资源对应的Content-Type是不一样的的,具体参照:http://tool.oschina.net/commons
- 对于文本类型的数据最好都加上编码,目的是为了防止中文解析乱码问题
- 通过网络发送文件
- 发送的并不是文件,本质上来讲发送的是文件的内容
- 当浏览器收到服务器响应内容之后,就会根据你的Content-Type进行相应的解析处理
var http = require('http')
var fs=require('fs')
var server = http.createServer()
server.on('request',function (req,res) {
// index.html
var url=req.url;
if (url==='/') {
// res.end('<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><h1>首页</h1></body></html>')
fs.readFile('./index.html',function (err,data) {
if (err) {
res.setHeader('Content-Type','text/plain;charset=utf-8')
res.end('文件读取失败,请稍后重试!')
}else{
//data默认是二进制数据,可以通过.toString转化为咱们能识别的字符串
//res.end() 支持两种数据类型,一种是二进制,一种是字符串
res.setHeader('Content-Type','text/html;charset=utf-8')
res.end(data)
}
})
} else if (url==='/hj') {
fs.readFile('./hudie.png',function (err,data) {
if (err) {
res.setHeader('Content-Type','text/plain;charset=utf-8')
res.end('文件读取失败,请稍后重试!')
}else{
//data默认是二进制数据,可以通过.toString转化为咱们能识别的字符串
//res.end() 支持两种数据类型,一种是二进制,一种是字符串
res.setHeader('Content-Type','image/png')
res.end(data)
}
})
}
})
server.listen(3000,function (params) {
console.log('Server is Running...')
})
无论你的代码是否有分号,都 建议你如果一行代码以( [ ` 开头的,最好前面补个分号;
为了约定大家的代码风格,所以在社区中诞生了一些比较规范的代码风格:
- JavaScript Standard Style
- Airbnb JavaScript Style