英文:
getitng "code: 'ERR_HTTP_HEADERS_SENT'" error while redirecting
问题
在尝试使用Node.js运行简单服务器时,我监听消息是否发布到"/msg",然后将消息写入entry.txt并将用户重定向到"/home"。但是,我遇到了错误code: 'ERR_HTTP_HEADERS_SENT'
,并在重定向用户时停止了服务器,导致显示无法访问此网站页面。
import http from "http";
import fs from "fs";
export default sample_server()
function sample_server() {
const server = http.createServer((req, res) => {
const { url, method } = req;
res.setHeader("Content-Type", "text/html");
if (url === "/home") {
res.write("<html>")
res.write("<head><title>page</title></head>")
res.write("<body><center><h1>welcome</h1>")
res.write("<form method='POST' action='/msg'>")
res.write("<input type='text' name='msg'>")
res.write("<input type='submit'>")
res.write("</form></center></body></html>")
return res.end()
} else if (url === "/msg" && method === "POST") {
res.write("<html>")
res.write("<head><title>page</title></head>")
res.write("<body><center><h1>massage</h1></center></body>")
res.write("</html>")
let msg = [];
req.on("data", chunk => {
msg.push(chunk)
})
req.on("end", () => {
msg = Buffer.concat(msg).toString().split("=")[1]
fs.appendFileSync("./files/entry.txt", `entered: ${msg}\n`)
})
res.writeHead(302, { Location: "/home" })
return res.end()
} else {
res.write("<html>")
res.write("<head><title>page</title></head>")
res.write("<body><center><h1>not found</h1></center></body>")
res.write("</html>")
return res.end()
}
})
server.listen(3030)
}
我想知道是否与req.on("data", () => {...})
或req.on("end", () => {...})
从响应中异步运行有关。
到目前为止,我尝试使用以下代码替代res.writeHead(302, { Location: "/home" });
:
res.statusCode = 302;
res.setHeader("Location", "/");
但是这并没有解决问题。
英文:
here I try to run simple server using nodejs
server listen for massage to be posted to "/msg" then it write down the message to entry.txt and redirect user to "/home"
but It get error code: 'ERR_HTTP_HEADERS_SENT'
and stop server while redirecting user witch result in display of This site can’t be reached page
import http from "http";
import fs from "fs";
export default sample_server()
function sample_server() {
const server = http.createServer((req ,res)=>{
const {url , method} = req;
res.setHeader("Content-Type", "text/html");
if(url === "/home"){
res.write("<html>")
res.write("<head><title>page</title></head>")
res.write("<body><center><h1>welcome</h1>")
res.write("<form method='POST' action='/msg'>")
res.write("<input type='text' name='msg'>")
res.write("<input type='submit'>")
res.write("</form></center></body></html>")
return res.end()
}else if(url === "/msg" && method ==="POST"){
res.write("<html>")
res.write("<head><title>page</title></head>")
res.write("<body><center><h1>massage</h1></center></body>")
res.write("</html>")
let msg = [];
req.on("data" , chunk => {
msg.push(chunk)
})
req.on("end" , () => {
msg = Buffer.concat(msg).toString().split("=")[1]
fs.appendFileSync("./files/entry.txt" , `entered: ${msg}\n`)
})
res.writeHead(302, { Location: "/home" })
return res.end()
}else{
res.write("<html>")
res.write("<head><title>page</title></head>")
res.write("<body><center><h1>not found</h1></center></body>")
res.write("</html>")
return res.end()
}
})
server.listen(3030)
}
I wonder if it got anything to do with req.on("data" , () => {...})
or req.on("end" , () => {...})
running async from respons
so far I tried using
res.statusCode = 302;
res.setHeader("Location", "/");
instead of res.writeHead(302, { Location: "/home" });
but I didn't solve the problem
答案1
得分: 0
你正在尝试在发送正文之后编写标头,但标头需要在正文之前发送。当你调用第一个 res.write()
时,这会导致 http 库发送标头(包括到那时设置的内容)。然后当你尝试稍后执行 res.writeHead(302, { Location: "/home" })
时,http 引擎意识到标头已经发送,因此你会收到错误 ERR_HTTP_HEADERS_SENT
,因为这就是 http 引擎正在发现的内容。你要求发送标头,但它们已经发送了。显然,你不能按照这个顺序执行操作。
当你发送重定向时,没有必要发送请求正文(浏览器不会显示正文,所以发送正文只是浪费资源)。
另外,正如我在评论中所说,你应该将 res.end()
放入 end
事件处理程序中,这样在完成读取输入流之前不会结束请求。
此外,在你的 http 服务器请求处理程序中不应该使用同步 I/O,因为这可能会破坏服务器扩展的能力。相反,使用异步文件 I/O。
要解决这四个问题,将代码从以下内容更改为以下内容:
res.writeHead(302, { Location: "/home" })
let msg = [];
req.on("data" , chunk => {
msg.push(chunk)
})
req.on("end" , () => {
msg = Buffer.concat(msg).toString().split("=")[1]
fs.appendFile("./files/entry.txt" , `entered: ${msg}\n`, (err) => {
if (err) {
console.log(err);
}
res.end();
});
});
这将解决你的问题。
英文:
You are trying to write the header AFTER you send the body, but the header needs to be sent before. When you call the first res.write()
, that causes the http library to send the headers (with whatever has been set up to that point). When you then try to do res.writeHead(302, { Location: "/home" })
later, the http engine realizes that the headers have already sent and thus you get the error ERR_HTTP_HEADERS_SENT
because that's literally what the http engine is discovering. You're asking to send headers, but they've already been sent. Obviously, you can't do things in that order.
There's also no point in sending a body to the request when you're sending a redirect (the browser won't display the body anyway so it's just a waste to send the body).
And, as I said in a comment, you should put the res.end()
into the end
event handler so you aren't ending the request until you're done reading the incoming stream.
And, you shouldn't be using synchronous I/O in your http server request handlers because that can ruin the ability of your server to scale. Instead, use asynchronous file I/O.
To fix all four of these, change from this:
res.write("<html>")
res.write("<head><title>page</title></head>")
res.write("<body><center><h1>massage</h1></center></body>")
res.write("</html>")
let msg = [];
req.on("data" , chunk => {
msg.push(chunk)
})
req.on("end" , () => {
msg = Buffer.concat(msg).toString().split("=")[1]
fs.appendFileSync("./files/entry.txt" , `entered: ${msg}\n`)
})
res.writeHead(302, { Location: "/home" })
return res.end()
to this:
res.writeHead(302, { Location: "/home" })
let msg = [];
req.on("data" , chunk => {
msg.push(chunk)
})
req.on("end" , () => {
msg = Buffer.concat(msg).toString().split("=")[1]
fs.appendFile("./files/entry.txt" , `entered: ${msg}\n`, (err) => {
if (err) {
console.log(err);
}
res.end();
});
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论