在Node.js中,假设提供请求需要时间。因此,在收到请求后,服务器想要回复“我恢复了您的请求,我会很快回复您”。然后,一旦处理请求结束,服务器希望这次使用实际响应返回客户端。我们怎么做? 下面的代码片段发出错误(连接已关闭或其他)。
'use strict';
var http = require('http');
var numberOfRequests = 0;
http.createServer(function (request, responce) {
request.n = numberOfRequests;
console.log('Request number ' + numberOfRequests + ' recioved!');
responce.writeHead(200);
responce.write("soon we will get back to you for your request# " + request.n);
responce.end();
setTimeout(function () {
responce.writeHead(200);
responce.write("Responce to your request# " + request.n);
console.log("Responce to the request# " + request.n);
responce.end();
}, 5000);
numberOfRequests++;
}
).listen(8080);
console.log('listening ...');
答案 0 :(得分:4)
您无法向同一请求发送两个回复。每个请求只能发送一个完全形成的响应。这是http规范。
我所知道的唯一解决方法是:
在刷新的流模式下使用http。在这里,您发送部分响应,将其刷新,以便您知道它已发送,并且您在另一个上有特殊类型的客户端读取部分响应并解释它们的结束(不是读取http响应的常用方式,而不是浏览器本身的响应方式)。
使用websocket或socket.io连接在最终发送实际的http响应之前用进度更新客户端。用户将连接socket.io连接,然后进行长时间运行的http请求,然后在socket.io连接上接收常规进度,然后在完成后接收http响应。这可以在任何网页上轻松完成,没有太大困难。要解决的唯一主要问题是你必须安装一个关联webSocket或socket.io连接的方法与传入的http连接(通常可以通过会话cookie完成),这样你就知道哪个webSocket或socket.io连接是关联的使用刚刚到达的http请求。
使用其他一些server-push scheme 将第二个响应“推送”到客户端。
实施客户端轮询。发送初始http响应,指示客户端以NN毫秒检查以查看响应是否还有更多内容。当客户端稍后再次检查NN ms时,您要么对它们进行最终响应并发送它,要么再次响应,告诉它们以NN ms等再次检查...
答案 1 :(得分:1)
您正在寻找服务器发送事件(SSE),当然您可以发送分块数据,只是在发送最后一条数据之前不要调用res.end()
。顺便说一句,你只能发送一次标题。见这个例子:
res.writeHead(200);
res.write("The first piece of data");
setTimeout(()=>{
res.write("This piece of data will be sent in 1 second.");
res.end("Ok, all data has be send, now close the connection.");
}, 1000);