【问题标题】:NodeJS stream pausing/resuming does not work with XMLHttpRequest, but works with curl?NodeJS 流暂停/恢复不适用于 XMLHttpRequest,但适用于 curl?
【发布时间】:2012-04-06 11:11:12
【问题描述】:

这是一个非常深奥的问题,我无法制作一个小的测试用例,所以提前抱歉。但也许有人以前遇到过类似的事情。

我有这样的代码(使用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 inside" 日志行比 "from outside" 日志行少。尽管我尽最大努力尽快暂停,但似乎其中一个数据事件正在丢失。


这是我正在使用的 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 数据连同原始请求一起发送)。即便如此,我也不知道为什么会这样。

【问题讨论】:

  • 你得到这个答案了吗?如果我真的可以使用 nodejs 暂停/恢复 http 响应?

标签: javascript http node.js xmlhttprequest arraybuffer


【解决方案1】:

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

所以大概在 CURL 情况下,时间足够好,pause 实际上按预期工作,而在 XMLHttpRequest 情况下,时间已关闭,"from outside" data 事件之一成功通过“建议”暂停。

显然有各种修复方法,在线程中进行了讨论,但我对整个流/缓冲区领域仍然很不稳定,所以我不会尝试在这个答案中推荐一个。

我添加了一个documentation pull request,希望没有其他人尝试使用pause,假设它确实有效。

【讨论】:

  • 好吧,pause 有效 但正如您所提到的,它是建议性的,并且是异步的。 pause 的一个非常有用的用例是在代理中:您从上游读取,然后写入客户端。如果写入客户端返回false,则表示缓冲区已满,可以向后端发送一个pause。您可能会从后端收到一些额外的数据块,但不是所有文件。如果没有暂停,代理 1 GB 文件会导致整个文件缓冲到内存中(并且您的 Node.js 进程会爆炸)。我希望这会有所帮助!
猜你喜欢
  • 2021-06-22
  • 2015-09-19
  • 1970-01-01
  • 2020-10-08
  • 2015-01-21
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 2022-06-21
相关资源
最近更新 更多