![](/img/trans.png)
[英]node.js ~ express req.on('end') triggers but not req.on('data')
[英]My req.on('end') does not fire. How can fix this?
我剛開始學習 Node.js,我正在嘗試打印通過表單提交的輸入值。 req.on('data')
總是觸發,但req.on('end')
永遠不會觸發。 請有人能告訴我出了什么問題嗎?
我的整個代碼可以在下面找到
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
if (url === '/') {
res.write('<html>');
res.write('<head><title>Enter Message</title></head>');
res.write(
'<body><form action="/message" method="POST"><input type="text" name="message"><button type="submit">Send</button></form></body>'
);
res.write('</html>');
return res.end();
}
if (url === '/message' && method === 'POST') {
const body = [];
req.on('data', (chunk) => {
console.log(chunk);
body.push(chunk);
});
req.on('end', () => {
const parsedBody = Buffer.concat(body).toString();
console.log(parsedBody);
});
res.statusCode = 302;
res.setHeader('Location', '/');
return res.end();
}
// process.exit();
res.setHeader('Content-Type', 'text/html');
res.write('<html>');
res.write('<head><title>My First Page</title></head>');
res.write('<body><h1>Hello from my Node.js Sever!</h1></body>');
res.write('</html>');
res.end();
});
server.listen(4000);
-------------------------------------------------- -----------------------------------------------
好的,所以我修復了它,但修復沒有意義
我不得不在if (url === '/message' && method === 'POST')
語句的末尾移動res.*
調用,並將它們放在res.on('end')
事件處理程序中:
req.on('end', () => {
const parsedBody = Buffer.concat(body).toString();
console.log(parsedBody);
res.statusCode = 302;
res.setHeader('Location', '/');
res.end();
});
然后我不得不在 if 語句之后刪除res.*
調用:
//res.setHeader('Content-Type', 'text/html');
//res.write('<html>');
//res.write('<head><title>My First Page</title></head>');
//res.write('<body><h1>Hello from my Node.js Sever!</h1></body>');
//res.write('</html>');
//res.end();
所以現在整個代碼看起來像這樣:
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
const url = req.url;
const method = req.method;
if (url === '/') {
res.write('<html>');
res.write('<head><title>Enter Message</title></head>');
res.write(
'<body><form action="/message" method="POST"><input type="text" name="message"><button type="submit">Send</button></form></body>'
);
res.write('</html>');
return res.end();
}
if (url === '/message' && method === 'POST') {
const body = [];
req.on('data', (chunk) => {
console.log(chunk);
body.push(chunk);
});
req.on('end', () => {
const parsedBody = Buffer.concat(body).toString();
console.log(parsedBody);
res.statusCode = 302;
res.setHeader('Location', '/');
return res.end();
});
}
// process.exit();
//res.setHeader('Content-Type', 'text/html');
//res.write('<html>');
//res.write('<head><title>My First Page</title></head>');
//res.write('<body><h1>Hello from my Node.js Sever!</h1></body>');
//res.write('</html>');
//res.end();
});
server.listen(4000);
任何有關為什么解決此問題的見解將不勝感激。
編輯
原始答案仍然適用,但我錯過了一件事: if
塊必須像原始帖子中一樣返回 - 否則將運行之后的響應操作,這將再次關閉 req/res 流。
返回或不返回事件處理程序沒有區別。 它不會影響執行並且返回值不會在任何地方使用。
因此,對於修訂后的修復程序:
if (url === '/message' && method === 'POST') {
// ...
req.on('end', () => {
const parsedBody = Buffer.concat(body).toString();
console.log(parsedBody);
res.statusCode = 302;
res.setHeader('Location', '/');
res.end();
});
return;
原答案
我不是 node http 模塊的專家,所以如果有人願意填寫,請填寫。 那說:
兩秒意味着底層連接超時(實際的套接字,它可能為額外的請求保持活動狀態)。 這是正常的。
我想這里發生的事情是,由於您本質上要求在耗盡請求流之前關閉響應流,因此即使有更多數據可用,請求流也將關閉。 請注意,實際的底層連接是雙向的,結束響應傳輸意味着您對傳入的消息不再感興趣。
要解決此問題,請將res.*
調用移動到'end'
事件處理程序:
req.on('end', () => {
const parsedBody = Buffer.concat(body).toString();
console.log(parsedBody);
res.statusCode = 302;
res.setHeader('Location', '/');
res.end();
});
經過一番研究,我發現了問題所在。 req.on('end')
事件處理程序剛剛注冊但沒有被觸發,因為它是異步的。 所以它移動到下一個代碼塊,即:
res.setHeader('Content-Type', 'text/html');
res.write('<html>');
res.write('<head><title>My First Page</title></head>');
res.write('<body><h1>Hello from my Node.js Sever!</h1></body>');
res.write('</html>');
res.end();
這會阻止req.on('end')
在請求流已關閉時執行。
我應該做的是返回req.on('end')
事件處理程序:
return req.on('end', () => {
const parsedBody = Buffer.concat(body).toString();
console.log(parsedBody);
res.statusCode = 302;
res.setHeader('Location', '/');
return res.end();
});
這將阻止執行if (url === '/message' && method === 'POST')
語句之后的req.*
語句塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.