91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Node中怎么處理HTTP請求

發布時間:2021-07-21 09:08:23 來源:億速云 閱讀:197 作者:Leah 欄目:大數據

本篇文章給大家分享的是有關Node中怎么處理HTTP請求,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

    首先使用express generator快速搭建一個express項目,命令:

express analysis_http

Node中怎么處理HTTP請求

按照提示進入項目安裝依賴,然后使用npm  start可以啟動express項目。那究竟我們項目是如何創建http服務器并且進行啟動的呢?express創建成功會在bin文件夾下生成www文件,里面有必須的啟動配置。我們可以看看www文件:

Node中怎么處理HTTP請求

我們初步可以看到,主要調用了http.createServer() server.listen()兩個方法。我們現在可能會有一系列疑問:

接口使用的req和res參數從何而來?createServer()如何創建服務器?listen()具體是進行了什么樣的操作?

接下來,我們通過源碼來具體分析這些問題。首先,從gitHub拉取一份NodeJS源碼,地址:

https://github.com/nodejs/node.git

我們先來查看lib/http.js文件關鍵代碼:

Node中怎么處理HTTP請求

我們可以看到createServer()方法返回的是Server的一個實例。而參數requestListener我們我們接口中的傳入的回調函數:

function(req, res, next) {    res.send('respond with a resource');}

在文件頂部可以看到Server引用的_http_server.js。所以我們去_http_server.js中看看Server這個構造函數:

Node中怎么處理HTTP請求

由于Server繼承net.Server,net.Server繼承自events.EventEmitter所以可以使用on等方法。我們可以看到在Server構造函數中設置了requestconnection事件的回調函數:

request使用了createServer中設置的回調方法requestListener。connection則使用了回調方法:connectionListener。

那我們什么時候會觸發connection事件呢?我們看下connectionListener關鍵源碼:

Node中怎么處理HTTP請求 

這里比較需要注意的有parser對象以及parseOnIncoming()。我們先來看看parser對象,parser來自parsers.alloc():

const parser = parsers.alloc();

從文件頂部可以看出parsers來自_http_common.js文件。我們可以看看源碼:

Node中怎么處理HTTP請求

我們可以看到,為了盡可能增加對parser進行重用,減少不斷調用構造函數的消耗,parser采用了FreeList的數據結構,FreeList池中設有上限1000parser是基于事件,使用了http-parser庫。然后可以看到兩個比較重要的方法:parseOnHeadersCompleteparserOnMessageComplete

parseOnHeadersComplete:請求頭解析完成則觸發本方法。parserOnMessageComplete:接收body完成后觸發本方法,數據接收完成會觸發end事件。

我們再來看看FreeList的源碼:

Node中怎么處理HTTP請求

http默認創建了1000http_parser實例,每次有http請求時,都會從數組中去除一個http_parser分配給當前的socket。如果1000http_parser全部分配完畢,則會分配新的http_parser。我們解析完請求頭會觸發parseOnHeadersComplete方法,如果不是udp類型請求,就會觸發request事件。

講完了parser對象,我們接著回到剛才說的parseOnInComing()方法。parseOnInComing()方法使用bind,并傳入參數parser,socket,state。

parser.onIncoming = parserOnIncoming.bind(undefined, server, socket, state);

我們先看看parseOnInComing()的源碼:

Node中怎么處理HTTP請求

里面有個重要的判斷為sockket._httpMessage。如果結果為true,說明有其他請求在占用socket。而parserOnInComing()方法用來處理解析完畢的請求,所以到這里代表解析請求頭和請求體已經完成了。而剛才已經講過:請求頭解析完畢會執行parserOnHeadersComplete()方法,我們看看parserOnHeadersComplete()方法的源碼:

Node中怎么處理HTTP請求

我們可以看到里面調用了parser.incoming,parser.incoming則是ParserInComingMessage(socket)的一個實例。ParserInComingMessage繼承自Stream.Readable。StreamNodeJS另一個尤其重要的知識點,不過本篇文章不進行深入講解。

Object.setPrototypeOf(IncomingMessage.prototype, Stream.Readable.prototype);Object.setPrototypeOf(IncomingMessage, Stream.Readable);

所以整體的邏輯應該為:

1.解析請求頭,就會觸發request事件。2.請求頭解析完畢執行parserOnHeadersComplete()方法。3.在parserOnHeadersComplete()方法中執行了parseOnIncoming()方法。4.最后server.emit('request', req, res)。

在觸發request事件的時候,傳入req, res參數。因為一開始我們說過了request綁定了回調方法:

function(req, res, next) {    res.end('respond with a resource');}

所以觸發request的時候回調方法被執行。但是body數據不會被解析,而body數據會一直存放在stream中,直到用戶觸發data事件來接收body中的數據。回調方法中會觸發res.end()事件。那究竟listen()是做了什么操作呢?

因為只有connection事件被觸發,才會觸發listen()事件。所以先看下onconnection()源碼:

Node中怎么處理HTTP請求

我們接著查看調用onconnection()方法的源碼:

setupListenHandle(address, port, addressType, backlog, fd)

Node中怎么處理HTTP請求

可以看到底部使用了_listen2。我們繼續查看調用_listen2源碼:

Node中怎么處理HTTP請求

可以看到內部調用了server._listen2。我們再次查看調用listenInCluster的源碼:

Node中怎么處理HTTP請求

我們是使用遞推,由下往上推出調用的方法,所以整體的流程應該是:

1.listen()調用listenInCluster(this, pipeName, -1, -1, backlog, undefined, options.exclusive);2.在listenInCluste()中調用server._listen2(address, port, addressType, backlog, fd, flags);3.接著調用了setupListenHandle(address, port, addressType, backlog, fd, flags);4.在setupListenHandle()中調用了onconnection()。5.最終回到listen()方法并且self.emit('connection', socket);

以上就是Node中怎么處理HTTP請求,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

玉树县| 桐城市| 伽师县| 嫩江县| 平江县| 汕头市| 兰考县| 嘉义县| 来宾市| 读书| 洪湖市| 镇巴县| 梁山县| 曲松县| 衢州市| 浏阳市| 洪雅县| 特克斯县| 于都县| 理塘县| 通海县| 府谷县| 扶风县| 元江| 新平| 牟定县| 武鸣县| 东阿县| 巴彦淖尔市| 松潘县| 泸州市| 建瓯市| 托里县| 金沙县| 东宁县| 综艺| 高青县| 内丘县| 华蓥市| 桦甸市| 祥云县|