【Node核心模塊HTTP】

環境:Node v8.2.1; Npm v5.3.0; OS Windows10
客戶端、服務端對咱們都不陌生,Node.js 中的 HTTP 接口被設計成支持協議的許多特性。 好比,大塊編碼的消息。 這些接口不緩衝完整的請求或響應,用戶可以以流的形式處理數據。app

爲了支持各類可能的 HTTP 應用,Node.js 的 HTTP API 是很是底層的。 它只涉及流處理與消息解析。 它把一個消息解析成消息頭和消息主體,但不解析具體的消息頭或消息主體。框架

一、API結構圖

因爲該模塊中的內容比較多,圖片我就分開傳了,避免一張圖密密麻麻的。socket

1.1 模塊類結構圖

圖片描述

1.2 Agent類結構圖

圖片描述

1.3 ClientRequest類結構圖

圖片描述

1.4 Server 類結構

圖片描述

1.5 ServerResponse類結構圖

圖片描述

1.6 IncomingMessage類結構圖

圖片描述

1.7 靜態方法和屬性圖

圖片描述

二、類關係

在看API以前,我仍是簡單的縷一縷上面幾個類的關係吧,從一個簡單的例子開始post

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個實例,能夠對照着頂部的那張圖看。ui

  • server:http.Server 類的實例,用來提供服務,處理客戶端的請求。
  • client:http.ClientRequest 類的實例,用於向服務端發起請求
  • clientReq/clientRes:http.IncomingMessage 類的實例,【clientReq】用於服務端獲取客戶端請求的信息,【clientRes】用於客戶端獲取服務端返回的相關消息
  • serverRes:http.ServerResponse 類實例,用於服務端響應客戶端請求

2.2 類關係圖

圖片描述

圖片有點亂,在畫圖本里面拖出來的,講究看吧,下面貼出繼承關係的源碼,只貼框架,裏面具體的內容就不貼了,貼出來感受蠻亂的。google

http.IncomingMessage 類繼承 stream.Readable:編碼

export class IncomingMessage extends stream.Readable {}

http.ServerResponse 類繼承stream.Writable:url

export class OutgoingMessage extends stream.Writable {}

export class ServerResponse extends OutgoingMessage {}

三、一些例子

下面是部分API的例子,對部分API的一個簡單代碼實現spa

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();
相關文章
相關標籤/搜索