NodeJS流暂停/恢复不适用于XMLHttpRequest,但适用于curl?

问题描述:

这是一个非常深奥的问题,我无法提前为此提供一个小测试用例。但是也许有人遇到过这样的事情。NodeJS流暂停/恢复不适用于XMLHttpRequest,但适用于curl?

我有这样的(使用的RESTify)代码:

server.put("/whatever", function (serverRequest, serverResponse, next) { 
    serverRequest.pause(); 

    serverRequest.on("data", function (chunk) { 
     console.log("from outside", chunk); 
    }); 

    doSomeAsyncStuff(function (err) { 
     serverRequest.on("data", function (chunk) { 
      console.log("from inside", chunk); 
     }); 
     serverRequest.on("end", function() { 
      next(); 
     }); 

     serverRequest.resume(); 
    }); 
}); 

当我使用curl打这个服务器,这个伟大的工程。但是当我用XMLHttpRequest命中它时,我得到了一个比我做的"from outside"日志行少"from inside"的日志行。尽管我尽最大努力暂停ASAP,但似乎其中一个数据事件正在消失。


这里是我使用curl命令:

curl -X PUT -T file.pdf http://localhost:7070/whatever -v 

这里是XMLHttpRequest代码(工作在最新版本的Chrome浏览器):

var arrayBuffer = fromElsewhere(); 
var xhr = new XMLHttpRequest(); 

xhr.open("PUT", "http://localhost:7070/whatever"); 
xhr.setRequestHeader("Content-Length", arrayBuffer.byteLength); 
xhr.setRequestHeader("Content-Type", "application/pdf"); 
xhr.send(arrayBuffer); 

一个显着区别是, CURL在上传之前似乎发送Expect: 100-continue,而XMLHttpRequest则没有。我尝试手动添加该标题,但当然实际上并没有做太多工作(即Chrome没有等待响应,它只是发送了所有PDF数据以及原始请求)。即便如此,我不知道为什么这会影响事情。

+0

你得到了这个答案吗?如果我真的可以使用nodejs暂停/恢复http响应? – akmsharma 2014-06-17 15:56:49

有些可预见的是,这与卷曲与XMLHttpRequest没有任何关系,而是与the fact that serverRequest.pause is only advisory; it doesn't actually pause right away相反。也就是说,它几乎没用。

所以在卷曲的情况下大概的时间是不够好是pause实际工作不如预期,而在XMLHttpRequest情况下,时机断,"from outside"data事件之一设法通过“咨询”暂停滑倒。

有明显这方面的修正,在线程讨论,但我仍然在这整个流/缓冲器宇宙相当不稳,所以我不会尝试推荐一个在这个答案。

我已经添加了一个documentation pull request希望没有人试图使用pause假设它实际上工作。

+0

好吧,'暂停'*工作*,但正如你所说,它是咨询,异步。一个非常有用的'暂停'用例就是在代理中:从上游读取并写入客户端。如果写入客户端返回“false”,则表示缓冲区已满,并且可以向后端发送“暂停”。您可能会从后端收到一些额外的数据块,但不会包含所有文件。如果没有暂停,进行代理1个GB的文件会导致缓存到内存中的整个文件(和你的Node.js进程爆炸)。我希望这有帮助! – jpetazzo 2012-11-04 15:46:55