Nodejs新手,res.on('data')只能得到一次数据的问题
Nodejs新手,res.on(‘data’)只能得到一次数据的问题
function start(route, handle) { http.createServer(function(request, response) { var postData = “test”; var pathname = url.parse(request.url).pathname;
request.addListener("end", function(test) {
route(handle, pathname, response, postData);
});
request.addListener("data", function(chunk) {
postData += chunk;
console.log("Recived post data chunk '" + chunk + "'.");
});
}).listen(8888);
}
如上的代码, 当把request的监听放到函数start中的时候data事件只会触发一次? 求教啊 新手,遇到这个问题很是纠结. 换on触发也没用.
Node.js 新手,res.on('data')
只能得到一次数据的问题
背景
在处理 HTTP 请求时,特别是 POST 请求时,你可能会遇到 request.on('data', callback)
只能接收到一次数据的情况。这通常是因为请求的数据可能还没有完全到达,而你的代码已经结束了对数据的监听。
示例代码
让我们来看一个简单的示例,展示如何正确地处理 POST 数据:
const http = require('http');
const url = require('url');
function start(route, handle) {
http.createServer((request, response) => {
let postData = '';
// 监听 'data' 事件来接收数据块
request.on('data', (chunk) => {
postData += chunk;
console.log(`Received POST data chunk '${chunk.toString()}'`);
});
// 监听 'end' 事件来处理所有数据
request.on('end', () => {
route(handle, url.parse(request.url).pathname, response, postData);
});
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(8888);
console.log('Server has started.');
}
// 这里可以定义路由处理函数
function route(handle, pathname, response, postData) {
console.log(`About to route a request for ${pathname}`);
if (typeof handle[pathname] === 'function') {
handle[pathname](response, postData);
} else {
console.log(`No request handler found for ${pathname}`);
response.writeHead(404, {'Content-Type': 'text/plain'});
response.end();
}
}
// 假设 handle 是一个对象,包含不同的路径对应的处理函数
const handle = {
'/': (response, postData) => {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('Home Page\n');
response.end();
},
'/upload': (response, postData) => {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('Upload Page\n');
response.end();
}
};
// 启动服务器
start(route, handle);
解释
-
request.on('data', callback)
:- 这个事件会在每次接收到数据块时被触发。你可以在回调函数中将这些数据块拼接起来。
-
request.on('end', callback)
:- 这个事件在所有的数据都已经被接收后触发。你可以在这个事件的回调函数中进行进一步的处理,比如调用路由处理函数。
通过这种方式,你可以确保即使数据分多次发送,你也能完整地接收到所有的数据并进行处理。
总结
确保你在处理 HTTP 请求时正确使用 request.on('data', callback)
和 request.on('end', callback)
来处理数据。这样可以避免只接收到一次数据的问题。
触发一次, 收到什么了?
我想 request 是不是不应该加 data listener。你这一加,server 不就收不到数据了,就没法 route 了。所以,你的data listener 被 server 的 data listener 覆盖了。
数据太小了。所以只有一次,你post个大文件上去看看
不知道你是怎么测试发出http请求的 如果是利用req = http.request();发出的请求,每一次调用req.write();都会发射data事件。 如果是浏览器的话,发送到你的服务器的数据流是不是只有一个,所以只会触发一次data事件
在Node.js中,request
对象是可读流(Readable Stream),当处理HTTP请求时,如果请求体比较大或分块传输(Chunked Transfer Encoding),那么data
事件可能会被触发多次。你的问题可能是因为request
对象的end
事件在所有数据都接收完毕后才会触发,而你在request
的end
事件里调用了路由处理函数,这导致后续的数据不再处理。
为了确保你能够正确处理所有的数据片段,你需要将request.on('data')
和request.on('end')
的监听器放在合适的位置,并且确保在处理完所有数据后再进行路由处理。
以下是一个修改后的示例代码:
const http = require('http');
const url = require('url');
function start(route, handle) {
http.createServer((request, response) => {
let postData = '';
const pathname = url.parse(request.url).pathname;
request.on('data', (chunk) => {
postData += chunk;
console.log(`Received POST data chunk '${chunk}'.`);
});
request.on('end', () => {
route(handle, pathname, response, postData);
});
}).listen(8888);
console.log('Server has started.');
}
// 假设route是一个已经定义好的路由处理函数
解释:
- 初始化
postData
为空字符串:这是用来存储从request
中接收到的所有数据。 - 监听
data
事件:每次接收到数据时,将数据追加到postData
中,并打印出接收到的数据片段。 - 监听
end
事件:当所有的数据都接收完毕时,调用路由处理函数route()
。
通过这种方式,你可以确保即使数据是分块传输的,你也能够完整地接收到所有的数据,并在所有数据都到达后进行处理。