如何在结束响应之前输出数据?

以下是我在Chrome 11和Firefox 4中testing的代码片段:

var http = require('http'); http.createServer(function(request, response){ // Write Headers response.writeHead(200); // Write Hello World! response.write("Hello World!"); // End Response after 5 seconds setTimeout(function(){ response.end(); }, 5000); }).listen(8000); 

正如你所看到的,我超时了response.end()所以我可以testingresponse.write是否在response.end之前输出。 根据我的经验,虽然不是。

有没有办法在结束响应之前输出数据,如发送数据包中的数据?

如果您将内容types更改为text / plain,例如:

 // Write Headers response.writeHead(200, {'Content-Type': 'text/plain'}); 

那么Firefox会立即显示内容。 铬似乎仍然缓冲(如果你写了更多的内容,铬会立即显示)。

实际上有一种方法可以在不设置Content-Type: text/plain情况下做到这一点,仍然使用text/html作为Content-Type ,但是您需要告诉浏览器期望数据块。

这可以像这样轻松完成:

 var http = require('http'); http.createServer(function(request, response) { response.setHeader('Connection', 'Transfer-Encoding'); response.setHeader('Content-Type', 'text/html; charset=utf-8'); response.setHeader('Transfer-Encoding', 'chunked'); response.write('hello'); setTimeout(function() { response.write(' world!'); response.end(); }, 10000); }).listen(8888); 

你应该知道,直到response.end()被调用,请求仍在发生,并阻止其他请求到你的nodejs服务器。
您可以通过在两个不同的选项卡上打开调用此页面(localhost:8888)来轻松地进行testing。 其中一个会等待10秒钟,另一个只会在第一个响应结束后才会得到响应的开始(意思是等待响应开始的时间为10秒,响应结束的时间为10秒)这个代码)。

你也可以通过运行几个nodejs进程并在它们之间进行负载平衡来传递这个障碍,但是这会变得复杂得多,并且是一个应该被采用的线程。:)

如果你想在Chrome中输出分块的纯文本 – 就像Firefox默认的那样 – 你需要使用'X-Content-Type-Options': 'nosniff'头。 请参阅什么是“X-Content-Type-Options = nosniff”?

 var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8', 'Transfer-Encoding': 'chunked', 'X-Content-Type-Options': 'nosniff'}); res.write('Beginning\n'); var count = 10; var io = setInterval(function() { res.write('Doing ' + count.toString() + '\n'); count--; if (count === 0) { res.end('Finished\n'); clearInterval(io); } }, 1000); }).listen(8888); 

如果输出是text/html则不需要此选项。

从此Chrome缺陷中find的解决scheme: 传输编码分块不支持文本/纯文本

以下是您需要注意的主要问题:

  • 指定一个字符集
  • 每个“chunk”将会被浏览器输出(至less,我在Chrome中注意到)通过一个新行(如果charset是text/html

像这样:

 res.setHeader('Content-Type', 'text/html; charset=utf-8'); res.write('a<br>'); setTimeout(function() { res.write('b<br>'); setTimeout(function() { res.write('c'); res.end(); }, 2000); }, 2000);