【Node核心模块HTTP】

来源:互联网 发布:农产品淘宝店铺取名 编辑:程序博客网 时间:2024/05/17 23:08

环境: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();

segmentfault【Node核心模块HTTP】同步更新