簡單瞭解 node http 模塊javascript
文章記錄了對http 模塊的簡單使用與理解。html
先寫個小例子java
服務端:node
let http = require('http')
let server = http.createServer((req, res) => {
let buf = []
req.on('data', data => {
buf.push(data)
})
req.on('end', () => {
let str = Buffer.concat(buf).toString()
res.end(str)
})
})
server.listen(8080, () => {
console.log('server start')
})複製代碼
請求報文由如下組成api
node http 模塊 在TCP鏈接的讀操做上,將數據解析成(以空行分割,報文頭和報文體):緩存
報文頭部分:
req.method
req.httpVersionMajor
req.httpVersionMinor
req.httpVersion
req.upgrade
...
req.headers = {
Content-Length: 15
Content-Type: application/x-www-form-urlencoded
... ...
}
//
報文主體部分:
一個可讀流對象req,能夠繼續報文主體數據的讀取複製代碼
服務端經過http.ServerResponse 實例,來向客戶端(數據請求方)返回本次請求數據。包括響應頭,響應體(內部經過socket來發送信息)。服務器
//中間有個空行
"HTTP/1.1 200 OK
Date: Sat, 30 Nov 2019 05:10:05 GMT
Connection: close
Content-Length: 25
"
+ 請求體部分數據或所有數據複製代碼
經過的方法app
// 具體使用參考文檔
// 設置頭部,頭部並無發送
response.setHeader(name, value)
// 設置頭部,向請求發送響應頭,此方法只能在消息上調用一次,而且必須在調用 response.end() 以前調用。
response.writeHead()
// 若是調用此方法而且還沒有調用 response.writeHead(),則將切換到隱式響應頭模式並刷新隱式響應頭。
// 這會發送一塊響應主體。 能夠屢次調用該方法以提供連續的響應主體片斷。
response.write()
// 此方法向服務器發出信號,代表已發送全部響應頭和主體,該服務器應該視爲此消息已完成。 必須在每一個響應上調用此 response.end() 方法。
response.end() 複製代碼
let http = require('http')
let options = {
host: 'localhost',
port: 8080,
method: 'POST',
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
}
// 請求並無 發出 req 是個可寫流
let req = http.request(options)
req.on('response', res => {
console.log(res.headers)
let buf = []
res.on('data', data => {
buf.push(data)
})
res.on('end', () => {
console.log(Buffer.concat(buf).toString())
})
})
// write 向請求體寫數據
req.write('name=luoxiaobu&title=http')
// 實際的請求頭將會與第一個數據塊一塊兒發送,或者當調用 request.end() 時發送。
req.end()複製代碼
大概代碼執行流程:socket
http.request() 返回 http.ClientRequest 類的實例。http.ClientRequest 內部建立了一個socket來發起請求。函數
ClientRequest 實例是能夠看作可寫流。若是須要使用 POST 請求上傳文件,則寫入到 ClientRequest 對象。
response事件 每次服務器端有數據返回響應時都會觸發。
http.IncomingMessage 對象,它可用於訪問本次服務器端返回的,響應狀態、消息頭、以及數據。
http客戶端:在TCP模塊套接字 socket 上,將求報文頭和報文主體組裝成數據發送出去,將接受的數據解析出響應報文頭和報文主體,。
//中間有個空行
"POST / HTTP/1.1
content-type: application/x-www-form-urlencoded
Host: localhost:8080
Connection: close
Transfer-Encoding: chunked
"
+ 請求體部分數據或所有數據複製代碼
經過的方法
// 具體使用參考文檔
const postData = querystring.stringify({
'msg': '你好世界'
});
const options = {
hostname: 'localhost:8080',
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
// 內部會處理 options 解析出頭部
const req = http.request(options, (res) => {
});
// 這會發送一塊響應主體。 能夠屢次調用該方法以提供連續的響應主體片斷。
response.write()
// 此方法向服務器發出信號,代表已發送全部響應頭和主體,該服務器應該視爲此消息已完成。 必須在每一個響應上調用此 response.end() 方法。
response.end() 複製代碼
響應報文圖:
響應報文由如下組成
node http 模塊 在TCP鏈接的讀操做上,將數據解析成:
報文頭部分:
res.statusCode = statusCode;
res.statusMessage = statusMessage;
res.httpVersionMajor
res.httpVersionMinor
res.httpVersion
res.upgrade
...
res.headers = {
Content-Length: 15
Content-Type: application/x-www-form-urlencoded
... ...
}
//
報文主體部分:
一個可讀流對象,能夠繼續報文主體數據的讀取複製代碼
文章記錄了對http 模塊的簡單使用與理解,要深刻理解http 模塊,還需多看文檔,代碼實踐。
文中例子比較粗糙,理解不許確之處,還請教正。
參考資料:<<圖解HTTP>>