我有一個 http 服務器偵聽埠 9090 - 將請求傳送到 stdout,如下所示:
let server = http.createServer((req, res) => {req.pipe(process.stdout)})
server.listen(9090)
當我像這樣發送帶有 curl 的東西時:
curl -XGET -T - 'http://localhost:9090' < /tmp/text-input
它有效,我在服務器的終端上看到了輸出
但是當我在節點中嘗試以下操作時:
const http = require('http')
const nurl = new URL("http://localhost:9090")
let request = http.request(nurl)
request.on('response', (res) => {
process.stdin.pipe(request)
})
request.end() // If I emit this, nothing happens. If I keep this, I get the below error
并嘗試像這樣運行它:node request.js < /tmp/text-input,我收到以下錯誤:
node:events:368
throw er; // Unhandled 'error' event
^
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at new NodeError (node:internal/errors:371:5)
at write_ (node:_http_outgoing:748:11)
at ClientRequest.write (node:_http_outgoing:707:15)
at ClientRequest.<anonymous> (/home/tomk/workspace/js-playground/http.js:17:7)
at ClientRequest.emit (node:events:390:28)
at HTTPParser.parserOnIncomingClient (node:_http_client:623:27)
at HTTPParser.parserOnHeadersComplete (node:_http_common:128:17)
at Socket.socketOnData (node:_http_client:487:22)
at Socket.emit (node:events:390:28)
at addChunk (node:internal/streams/readable:324:12)
Emitted 'error' event on ClientRequest instance at:
at emitErrorNt (node:_http_outgoing:726:9)
at processTicksAndRejections (node:internal/process/task_queues:84:21) {
code: 'ERR_STREAM_WRITE_AFTER_END'
}
我想以與curl -T -. 我的請求代碼有什么問題?
uj5u.com熱心網友回復:
簡答
要在節點中發送分塊編碼訊息,請使用 POST 方法:
let request = http.request(nurl, { method: 'POST' })
process.stdin.pipe(request)
稍長(但部分)的答案
我打開了一個監聽 netcat(在普通 tcp 上監聽),nc -l 9090以查看請求curl與我的代碼有何不同,并在標頭中發現了一些關鍵差異。
在 curl 中,標頭Transfer-Encoding: chunked出現了,但在我的代碼發出的請求中丟失了。另外,我的代碼有一個標題Connection: closed
我記錄了請求物件并發現它useChunkedEncodingByDefault設定為false,鑒于來自 nodejs http docs的參考,這令人困惑:
發送“Content-Length”標頭將禁用默認的分塊編碼。
暗示它應該是默認值。
但后來我在節點的來源中找到了這個
if (method === 'GET' ||
method === 'HEAD' ||
method === 'DELETE' ||
method === 'OPTIONS' ||
method === 'TRACE' ||
method === 'CONNECT') {
this.useChunkedEncodingByDefault = false;
} else {
this.useChunkedEncodingByDefault = true;
}
因此,總而言之,節點不允許使用分塊編碼發送 GET 請求,但允許curl。奇怪,不幸的是沒有記錄(據我所知),但重要的是我讓它作業
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/339129.html
