[英]Error: Can't set headers after they are sent for HTTP node server
我試圖根據url值將多個值傳遞到服務器。
因為我有如下結果值
[ { url: 'account/41',
status: '200',
headers:
[ 'content-type = application/json,',
'content-type = application/text' ],
body: [ '{ name: XYZ }' ] },
{ url: 'account/43',
status: '201',
headers: [ 'content-type = application/xml']
body: [ '{ name : ZYX }' ] } ]
在這里,我正在嘗試為上述多個值創建服務器請求/響應。 我使用forEach循環進行迭代,例如url = account / 41,則body將返回['{name:XYZ}']};如果url = account / 43,則body將返回['{name:ZYX}']。 但是它只取結果值的第一個元素,並給我下面的錯誤:
UnhandledPromiseRejectionWarning: Error: Can't set headers after they are sent.
我想念的東西,但不確定嗎? 如何通過正確的輸出一一傳遞值。
const http = require('http')
const parse = require('./Parse.js')
// create a server object:
let server = http.createServer(function(request, response) {
parse.allFiles().then( results => {
results.forEach(element => {
if (element.url.includes(request.url) ) {
let headerSplit = ( element.headers + '' ).split('=')
let headername = headerSplit[0]
let headerVal = headerSplit[1]
response.setHeader( headername, headerVal )
response.write( JSON.stringify( element.body ) )
response.statuscode = parseInt( element.status )
response.end()
} else {
response.writeHead(404, {'Content-Type': 'text/html'})
response.end('No Page Found')
}
})
})
})
const port = process.env.PORT || 8080
server.listen(port, function() {
// eslint-disable-next-line no-console
console.log('Listening on port ' + port)
})
我有多個文件,這些文件帶有自己的URL,STATUS,HEADERS和BODY。 在單個數組中解析了這些值(使用Parse函數)之后,我進入了名為result的變量。
[{"url":"account/41","status":"200","headers":["content-type = application/json,"],"body":["{ name: xyz}"]},
{"url":"account/43","status":"201","headers":["content-type = application/xml"],"body":["{ name : zyx}"]}]
如果您對結果進行迭代,則會得到類似{“ url”:“ account / 41”,“ status”:“ 200”,“ headers”:[“ content-type = application / json”],“ body”的元素:[“ {name:xyz}”]},如果在服務器中傳遞url,例如localhost:8080 / account / 41,它將作為響應正文返回[“ {name:zyx}”]}]]作為響應。
您在.forEach()
循環中有一個response.end()
。 這意味着您要多次調用它。 您只能為每個請求調用一次,因為當您調用它時,將寫入標頭,刷新所有寫緩沖區並結束請求(例如,關閉套接字)。 因此,您不能多次“結束”請求。 由於您的results.forEach()
循環是同步的,因此您似乎可以在循環完成后將response.end()
放在某個位置,因此僅在循環中所有response.write()
調用完成后才調用一次。
您還必須修復循環中的其他內容,因為您似乎正在決定在循環中間的某個位置,如果循環中的某一項不起作用,則將返回404。 我不知道您應該在其中采用什么邏輯。 也許您應該跳過任何通過if
測試的項目,如果沒有匹配項if
僅發送404?
您還試圖在循環內一遍又一遍地設置狀態和特定的標頭。 那些只能有一個值,因此不清楚為什么要在循環中一遍又一遍地設置它。 只有循環的最后一次迭代會停留。
因此,關於如何處理循環的邏輯實際上只是有缺陷的。 為了使我們知道如何重新制作循環以使其正常工作,我們將必須更多地了解數據的外觀以及您希望響應的外觀。
要修復的問題列表:
response.end()
。 response.statuscode
只能有一個值,因此不清楚為什么要在循環中多次調用它。 您仍然沒有真正解釋您要構建的響應,但是我會猜測。 如果找到element.url.includes(request.url)
,那么您想發送該響應並停止循環並完成。 如果您在任何一個results
都沒有找到element.url.includes(request.url)
,那么您想發送一個404。如果是這樣,您可以這樣做:
const server = http.createServer(function(request, response) {
parse.allFiles().then(results => {
// find first element.url that matches our request.url
const match = results.find(element => element.url.includes(request.url));
if (match) {
let headerSplit = (match.headers + '').split('=');
let headername = headerSplit[0];
let headerVal = headerSplit[1];
response.setHeader(headername, headerVal);
response.write(JSON.stringify(match.body));
response.statuscode = parseInt(match.status);
response.end()
} else {
response.writeHead(404, {
'Content-Type': 'text/plain'
})
response.end('No Page Found')
}
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.