我正在尝试根据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}”]},如果您将网址传递给服务器,例如localhost:8080 / account / 41,它将作为响应返回[“ {name:zyx}”]}]]身体。
答案 0 :(得分:3)
您在response.end()
循环中有一个.forEach()
。这意味着您要多次调用它。您只能为每个请求调用一次,因为当您调用它时,将写入标头,刷新所有写缓冲区并结束请求(例如关闭套接字)。因此,您不能多次“结束”请求。由于您的results.forEach()
循环是同步的,因此看来您可以将response.end()
放在循环完成后的某个位置,因此只有在循环中的所有response.write()
调用完成后才调用一次。
您还必须修复循环中的其他内容,因为您似乎决定在循环中间的某个位置,如果循环中的某一项不起作用,则将返回404。我不知道您应该在其中采用什么逻辑。也许您应该跳过任何通过if
测试的项目,仅在不匹配的情况下发送404?
您还试图在循环内一遍又一遍地设置状态和特定的标头。那些只能有一个值,因此不清楚为什么要在循环中一遍又一遍地设置它。只有循环的最后一次迭代会停留。
因此,关于如何处理循环的逻辑确实存在缺陷。为了让我们知道如何重新制作循环以使其正常工作,我们必须更多地了解数据的外观以及您希望响应的外观。
要解决的问题列表:
response.end()
。response.statuscode
只能有一个值,因此不清楚为什么要在循环中多次调用它。您仍然没有真正解释您想要构建的响应,但是我会猜测。如果找到element.url.includes(request.url)
,则要发送该响应并停止循环并完成。如果您在element.url.includes(request.url)
的任何一个中都找不到results
,那么您想发送一个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')
}
});
});