Nodejs res.on的end事件

Nodejs res.on的end事件

直接上代码 server.js

var qs = require('querystring');
require('http').createServer(function (req, res) {
    var body = '';
    req.on('data', function (chunk) {
        body += chunk;
    });
    req.on('end', function () {
        res.writeHead(200);
        res.end('Done');
        console.log('\n got name \033[90m' + qs.parse(body).name + '\033[39m\n');
    });
}).listen(3000);

client.js

var http = require('http'),
    qs = require('querystring');

function send (theName) {
    http.request({
        host : '127.0.0.1',
        port : 3000,
        url : '/',
        method : 'POST'
    }, function (res) {
        res.setEncoding('utf-8');

        res.on('end', function () {
            console.log('\n \033[90m request complete!\033[39m');
            process.stdout.write('\n your name: ');
        });
    }).end(qs.stringify({name : theName}));
}

process.stdout.write('\n your name: ');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
process.stdin.on('data', function (data) {
    send(data.replace('\n',''));
});

问题:

按说在client端出现your name: 的提示之后,我输入名字,按回车之后server端就会出现your name ***,而client端将会出现request complete!your name:的提示,但是为什么我的client端就是不会出现这两句话啊?


2 回复

Nodejs res.on的end事件

在Node.js中,res.on('end') 事件用于监听HTTP响应流的结束。当客户端发送一个请求到服务器,并且服务器处理完该请求后,会触发 res.on('end') 事件。这个事件通常在响应体的所有数据都被读取完毕后被触发。

让我们通过以下代码来理解 res.on('end') 事件是如何工作的。

server.js

var qs = require('querystring');
require('http').createServer(function (req, res) {
    var body = '';
    req.on('data', function (chunk) {
        body += chunk;
    });
    req.on('end', function () {
        res.writeHead(200);
        res.end('Done');
        console.log('\n got name \033[90m' + qs.parse(body).name + '\033[39m\n');
    });
}).listen(3000);

在这段代码中,服务器监听端口3000,并且当接收到请求时,它会读取请求体中的数据并将其拼接到 body 变量中。当请求结束时(即 req.on('end') 触发),服务器解析请求体中的 name 参数,并打印出来,然后发送一个HTTP响应状态码为200和响应体 “Done”。

client.js

var http = require('http'),
    qs = require('querystring');

function send (theName) {
    http.request({
        host : '127.0.0.1',
        port : 3000,
        path : '/', // 使用path而不是url
        method : 'POST'
    }, function (res) {
        res.setEncoding('utf-8');

        res.on('end', function () {
            console.log('\n \033[90m request complete!\033[39m');
            process.stdout.write('\n your name: ');
        });
    }).end(qs.stringify({name : theName}));
}

process.stdout.write('\n your name: ');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
process.stdin.on('data', function (data) {
    send(data.replace('\n',''));
});

在这段代码中,客户端向服务器发送一个POST请求。当请求完成后,客户端会触发 res.on('end') 事件,并打印出 “request complete!” 和 “your name:” 提示。

解决问题

问题在于客户端代码中的 http.request 方法的配置项中使用了 url 而不是 path。正确的配置应该是 path

修改后的 client.js 应该是:

var http = require('http'),
    qs = require('querystring');

function send (theName) {
    http.request({
        host : '127.0.0.1',
        port : 3000,
        path : '/', // 使用path而不是url
        method : 'POST'
    }, function (res) {
        res.setEncoding('utf-8');

        res.on('end', function () {
            console.log('\n \033[90m request complete!\033[39m');
            process.stdout.write('\n your name: ');
        });
    }).end(qs.stringify({name : theName}));
}

process.stdout.write('\n your name: ');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
process.stdin.on('data', function (data) {
    send(data.replace('\n',''));
});

通过以上修改,客户端应该能够正确地接收服务器的响应,并在控制台输出 “request complete!” 和 “your name:” 提示。


在你的代码中,客户端发送请求后并没有正确地处理响应。具体来说,res.on('end', ...) 事件处理器可能没有被触发,因为服务器返回的响应可能是错误的或者客户端没有正确接收响应数据。

我们可以通过以下改进来解决这个问题:

客户端代码(client.js)

确保客户端正确接收并处理服务器响应。可以增加一些日志来调试问题:

var http = require('http'),
    qs = require('querystring');

function send(theName) {
    http.request({
        host: '127.0.0.1',
        port: 3000,
        path: '/',  // 修改为 path 而不是 url
        method: 'POST'
    }, function (res) {
        let responseBody = '';

        res.on('data', function (chunk) {
            responseBody += chunk;
        });

        res.on('end', function () {
            console.log('\n\033[90mrequest complete!\033[39m');
            console.log('\033[90mresponse body:\033[39m', responseBody);
            process.stdout.write('\n\033[90myour name:\033[39m ');
        });
    }).end(qs.stringify({name: theName}));
}

process.stdout.write('\n\033[90myour name:\033[39m ');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
process.stdin.on('data', function (data) {
    send(data.replace('\n', ''));
});

解释

  1. 修改请求路径:将 url 改为 path,这是正确的属性名。
  2. 处理响应数据:在 res.on('data', ...) 中累积响应数据,并在 res.on('end', ...) 中输出完整响应体。

这样可以确保客户端能够正确接收到服务器的响应,并打印出完整的响应体,从而帮助你更好地理解问题所在。

回到顶部