环境:Node v8.2.1; Npm v5.3.0; OS Windows10
客户端、服务端对我们都不陌生,Node.js 中的 HTTP 接口被设计成支持协议的许多特性。 比如,大块编码的消息。 这些接口不缓冲完整的请求或响应,用户能够以流的形式处理数据。为了支持各种可能的 HTTP 应用,Node.js 的 HTTP API 是非常底层的。 它只涉及流处理与消息解析。 它把一个消息解析成消息头和消息主体,但不解析具体的消息头或消息主体。
1、API结构图
由于该模块中的内容比较多,图片我就分开传了,避免一张图密密麻麻的。
1.1 模块类结构图
1.2 Agent类结构图
1.3 ClientRequest类结构图
1.4 Server 类结构
1.5 ServerResponse类结构图
1.6 IncomingMessage类结构图
1.7 静态方法和属性图
2、类关系
在看API之前,我还是简单的缕一缕上面几个类的关系吧,从一个简单的例子开始
2.1 简单且核心的例子
const http = require("http");//serverconst server = http.createServer((clientReq,serverRes)=>{ serverRes.end();}).listen(3000)//clientconst client=http.get("http://localhost:3000",(clientRes)=>{ })
上面那么简单的几行代码已经成功创建了一个server和一个client,看似简单,实际上却不这样,上面代码以一共创建了4个实例,可以对照着顶部的那张图看。
- server:http.Server 类的实例,用来提供服务,处理客户端的请求。
- client:http.ClientRequest 类的实例,用于向服务端发起请求
- clientReq/clientRes:http.IncomingMessage 类的实例,【clientReq】用于服务端获取客户端请求的信息,【clientRes】用于客户端获取服务端返回的相关消息
- serverRes:http.ServerResponse 类实例,用于服务端响应客户端请求
2.2 类关系图
图片有点乱,在画图本里面拖出来的,讲究看吧,下面贴出继承关系的源码,只贴框架,里面具体的内容就不贴了,贴出来感觉蛮乱的。
http.IncomingMessage 类继承 stream.Readable:
export class IncomingMessage extends stream.Readable {}
http.ServerResponse 类继承stream.Writable:
export class OutgoingMessage extends stream.Writable {}export class ServerResponse extends OutgoingMessage {}
3、一些例子
下面是部分API的例子,对部分API的一个简单代码实现
3.1 server属性
const http = require("http");const server=http.createServer((ClientRequest,ServerResponse)=>{ ServerResponse.end();})server.listen(3000);console.log("listening: "+server.listening);console.log("maxHeadersCount: "+server.maxHeadersCount);console.log("timeout: "+server.timeout);console.log("keepAliveTimeout: "+server.keepAliveTimeout);// listening: true// maxHeadersCount: null (没有限制)// timeout: 120000// keepAliveTimeout: 5000
3.2 server事件
const http = require("http");const server = http.createServer((ClientRequest, ServerResponse) => { ServerResponse.end();}).listen(3000);server.on("request", (request, response) => { console.log("服务端收到请求");})server.on("connection",socket=>{ //超过默认的5000msTCP流会被关闭,再次请求时会被重新建立 console.log("一个新的 TCP 流被建立");})
3.3 serverResponse属性
const http = require("http");const server = http.createServer((ClientRequest, ServerResponse) => { ServerResponse.writeHead(200, { 'Content-Type': 'text/plain'}); ServerResponse.write("hello world"); console.log("connection: "+ServerResponse.connection); console.log("finished: "+ServerResponse.finished); console.log("headersSent: "+ServerResponse.headersSent); console.log("sendDate: "+ServerResponse.sendDate); console.log("socket: "+ServerResponse.socket); console.log("statusCode: "+ServerResponse.statusCode); console.log("statusMessage: "+ServerResponse.statusMessage); ServerResponse.end(); console.log("finished: "+ServerResponse.finished);}).listen(3000);/* connection: [object Object] finished: false headersSent: true sendDate: true socket: [object Object] statusCode: 200 statusMessage: OK finished: true*/
3.4 addTrailers()
const http = require("http");const server = http.createServer((ClientRequest, ServerResponse) => { ServerResponse.writeHead(200, { 'Content-Type': 'text/plain' }); ServerResponse.write("hello world"); ServerResponse.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'}) ServerResponse.end();}).listen(3000);
3.5 getHeader()
const http = require("http");const server = http.createServer((ClientRequest, ServerResponse) => { ServerResponse.setHeader("foo","bar"); ServerResponse.writeHead(200, { 'Content-Type': 'text/plain' }); ServerResponse.write("hello world"); console.log(ServerResponse.getHeader("foo")); ServerResponse.end();}).listen(3000);
3.6 getHeaderNames()
const http = require("http");const server = http.createServer((ClientRequest, ServerResponse) => { ServerResponse.setHeader("foo","bar"); ServerResponse.writeHead(200, { 'Content-Type': 'text/plain' }); ServerResponse.write("hello world"); console.log(ServerResponse.getHeaderNames()); //[ 'foo', 'content-type' ] ServerResponse.end();}).listen(3000);
3.7 get()
const http = require("http");const ClientRequest = http.get("http://localhost:3000", res => { res.setEncoding("utf8") let rawData = ''; res.on("data", chunk => { rawData += chunk; }) res.on("end", () => { console.log(rawData); })})ClientRequest.on("response", (imsg) => { console.log("收到响应");})
3.8 http.request
摘一个官方例子^_^
const postData = querystring.stringify({ 'msg' : 'Hello World!'});const options = { hostname: 'www.google.com', port: 80, path: '/upload', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) }};const req = http.request(options, (res) => { console.log(`状态码: ${res.statusCode}`); console.log(`响应头: ${JSON.stringify(res.headers)}`); res.setEncoding('utf8'); res.on('data', (chunk) => { console.log(`响应主体: ${chunk}`); }); res.on('end', () => { console.log('响应中已无数据。'); });});req.on('error', (e) => { console.error(`请求遇到问题: ${e.message}`);});// 写入数据到请求主体req.write(postData);req.end();