簡體   English   中英

我的 req.on('end') 沒有觸發。 如何解決這個問題?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM