Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在服务器上手动取消XMLHttpRequest文件上载(流)_Javascript_Node.js_Express_Stream_Xmlhttprequest - Fatal编程技术网

Javascript 如何在服务器上手动取消XMLHttpRequest文件上载(流)

Javascript 如何在服务器上手动取消XMLHttpRequest文件上载(流),javascript,node.js,express,stream,xmlhttprequest,Javascript,Node.js,Express,Stream,Xmlhttprequest,我正在使用XMLHttpRequest(级别2)将文件上载到node.js服务器。我正在服务器端检查文件流中的有效头。现在我想触发一个取消上传,如果有任何错误,而流。我的XMLHttpRequest代码非常简单: var xhr = new XMLHttpRequest(); var file; $('#file').on('change', function(e) { file = this.files[0]; file.filename = this.files[0].name; }

我正在使用XMLHttpRequest(级别2)将文件上载到node.js服务器。我正在服务器端检查文件流中的有效头。现在我想触发一个取消上传,如果有任何错误,而流。我的XMLHttpRequest代码非常简单:

var xhr = new XMLHttpRequest();
var file;
$('#file').on('change', function(e) {
  file = this.files[0];
  file.filename = this.files[0].name;
});
$('#submit').on('click', function(e) {
  e.preventDefault();
  xhr.open('POST', '/upload', true);
  xhr.send(file);
});
在服务器端,我通过我的验证器将req流传输到一个文件流中。如果验证过程中出现任何错误,我希望XMLHttpRequest中止上载。但是仅仅发送400作为对请求的响应根本不起作用。我在xhr上注册了各种各样的听众,但没有一个会开火。它似乎根本不关心400,仍然试图上传文件。通常,我希望onreadystatechange事件会在这种情况下触发

我试图通过发出一个req.end()来关闭req,但这似乎有点苛刻,并显示出另一种好奇。如果我这样做,XMLHttpRequest将重试发送POST请求整整7次(在Chrome中;在Firefox中为5次;这是否有文档记录?)

编辑:正如保罗所建议的:

…在从服务器接收任何状态之前关闭连接

在服务器端,我尝试侦听响应的finish事件

  checkedFile.on('error', function (err) {
    res.status(400);
    res.end();
  });

  res.on('finish', function () {
    req.destroy();
  });
但它还是会重试。我只是不在乎400

也许有另一种方法可以在不破坏请求流的情况下取消

第二次编辑:可以在不破坏请求流的情况下结束请求:

checkedFile.on('wrong', function (err) {
  checkedFile.end();
  res.writeHead(400,  { 'Connection': 'close' });
  res.end();
});

但XHR仍在重试请求。

在某些情况下,如果服务器过早关闭连接,则允许客户端重试请求,这就是Chrome在您的示例中所做的。此行为在中定义:

如果HTTP/1.1客户端发送的请求包含请求正文,但不包含带有“100 continue”期望值的Expect request header字段,并且如果客户端未直接连接到HTTP/1.1源服务器,并且如果客户端在从服务器接收任何状态之前看到连接已关闭,客户端应重试该请求


如果你想取消XMLHttpRequest,你应该监听XHR的
错误
事件,然后调用它,这将阻止Chrome重新发送请求。

好吧,看来你必须接受以下情况:


顺便说一句,如果您检查文件头的内容类型,您也会遇到同样的问题。

再次感谢您的回答。在我的例子中,问题是“error”事件是在7次重试后触发的。在这两者之间,除了“progress”事件之外,没有任何通信。即使您的Express服务器调用
req.end()
,我也对此进行了更多的研究。在我的例子中,由于某种原因,我不得不使用req.destroy(),而不是req.end(),因为后者没有在req上定义。如果我在发送400之后销毁了req,那么它只会重试一次(我猜是因为延迟)。所以我试着去听res的“关闭”事件,但从来没有发生过。看我编辑的问题。所有这些对我来说都失败了。请看。