这篇文章主要讲述,Node.js的原生的web 服务器开发。目的是掌握node基础的web服务器开发中所用到的api, 以及代码模块化思想,为以后的框架使用作为基础。
1.使用node http模块
http模块是node.js 官方提供的,用来创建web服务器的模块。其内部实现原理是使用C++。
node.js 可以提供改功能的模块还有http2 和https。
1.1 那么三者之间有什么区别?
HTTP (The HyperText Transfer Protocol,超文本传输协议) 是用于在 Web 上传输超媒体文件的底层 协议 ,最典型场景的是在浏览器和服务器之间传递数据,以供人们浏览。现行的 HTTP 标准的版本是 HTTP/2。
HTTP2
相对于http 主要做的优化有 多路复用、服务器推送、头信息压缩、二进制协议等
HTTP2,传输的不再是文本,而是二进制流。文本的好处是人可以阅读,二进制流的好处是减少了文本带来的二义性,便于机器阅读。但是同时,HTTP2对于HTTP1.1是兼容的。
HTTPS
过HTTPS是身披SSL外壳的HTTP。HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。
PS:TLS是传输层加密协议,前身是SSL协议,由网景公司1995年发布,有时候两者不区分
示例代码
var http = require('http');
// http是网络模块。createServer方法就是创建服务,调用它以后会生成一个服务对象。
var server = http.createServer();
// 设置超时时间(默认是120s)
server.setTimeout(60 * 1000, () => {
console.log('超时回调');
});
2.监听端口
listen方法是监听浏览器请求,第一个参数是端口号,第二个是回调,可以让后端看到服务是否正常。
示例代码
var http = require('http')
var serve = http.createServer();
serve.listen('3000', ()=>{
})
3.绑定请求事件
‘request’ 事件
新增于: v0.1.0
request <http.IncomingMessage>
response <http.ServerResponse>
每次接收到一个请求时触发。 注意,每个连接可能有多个请求(在 HTTP keep-alive 连接的情况下)。
使用serve.on()为服务器实例绑定request 事件,此方法第一个参数为request请求 第二个参数为response响应
示例代码
server.on('request', function(req, res){
})
4. 请求对象
http.ClientRequest 类
该对象在 http.request() 内部被创建并返回。 它表示着一个正在处理的请求,其请求头已进入队列。
请求头仍可使用 setHeader(name, value)、getHeader(name) 和 removeHeader(name) API 进行修改。 实际的请求头会与第一个数据块一起发送或当调用 request.end() 时发送。
只要服务器接收到了客户端的请求,就会调用通过 server.on() 为服务器绑定的 request 事件处理函数。
在 ‘response’ 事件期间,可以添加监听器到响应对象上,比如监听 ‘data’ 事件。
如果没有添加 ‘response’ 事件处理函数,则响应会被整个丢弃。
如果添加了 ‘response’ 事件处理函数,则必须消耗完响应对象的数据,可通过调用 response.read()、或添加一个 ‘data’ 事件处理函数、或调用 .resume() 方法。
数据被消耗完时会触发 ‘end’ 事件。
在数据被读取完之前会消耗内存,可能会造成 ‘process out of memory’ 错误。
示例代码
const http = require("http")
const server = http.createServer()
server.on("request",function(req,res){
// 请求方法
console.log(req.method);
// 请求路径
console.log(req.url);
let data = '';
// 数据接受
req.on(
'data', function(chunk){
// 客户端传入数据
// console.log(1, chunk);
data +=chunk;
}
)
// 数据接受停止
req.on('end', function(){
// 数据解析
control.userInfo(require('querystring').parse(data), res)
})
})
server.listen(80,()=>{
console.log(1)
})
请求的内容少的话就直接在请求头协议完成之后立即读取,请求体可能相对较长一点,需要一定的时间传输。因此提供了三个事件用于控制请求体传输.
(1)data:当请求体数据到来时,该事件被触发,该事件一共一个参数chunk,表示接受到的数据。
(2)end:当请求体数据传输完成时,该事件被触发,此后将不会再有数据到来。
(3)close:用户当前请求结束时,该事件被触发,不同于end,如果用户强制终止了传输,也会触发close
5.响应对象
// 为了防止中文显示乱码的问题,需要设置响应头 Content-Type 的值为 text/html; charset=utf-8
res.setHeader("Content-Type","text/html;charset=utf-8")
res.write('hello we are family<br>');
res.end('server already end\n');