环境: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");
//server
const server = http.createServer((clientReq,serverRes)=>{
serverRes.end();
}).listen(3000)
//client
const 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();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。