如何手动取消服务器上的 XMLHttpRequest 文件上载(流)
How do I manually cancel a XMLHttpRequest file upload (stream) on the server
我正在使用XMLHttpRequest(Level 2)将文件上传到节点.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 次;这是否记录在任何地方?)。
编辑:正如保罗建议的那样:
。在从服务器接收任何状态之前连接关闭...
在服务器端,我尝试侦听响应的完成事件。
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 规范 8.2.4 中定义:
如果 HTTP/1.1 客户端发送的请求包含请求正文,但不包含预期为"100-continue"的 Expect 请求标头字段,并且客户端未直接连接到 HTTP/1.1 源服务器,并且客户端在从服务器接收任何状态之前看到连接关闭, 客户端应重试请求。
如果要取消 XMLHttpRequest,则应侦听 XHR 的 error
事件,然后调用其 abort()
方法,这将阻止 Chrome 重新发送请求。
好吧,似乎必须忍受这个:
如果未收到请求响应,会发生什么情况?我看到重试次数
超时的 POST 请求的浏览器重试行为不一致
http://geek.starbean.net/?p=393
顺便说一下,如果您正在检查内容类型的文件头,则会遇到同样的问题。
- 通过CSV文件上载更新数据库表
- 带有凭据的角度文件上载(CORS)不起作用
- 使用AJAX将文件上载到服务器
- 需要帮助处理XML HTTP文件上载请求
- 使用Javascript中的Dropbox Core API将文件上载到Dropbox
- JQuery文件上载未检测到动态添加的输入
- 通过将文件上载到ASHX处理程序来实现SSE(服务器发送的事件)
- 将 FormData 对象放入数组中以从不同的输入文件上载文件
- 恢复连接后上载文件
- 在react native中通过PUT方法上载文件
- 钛HTTPCLIENT可以't上载文件
- AJAX POST函数未上载文件
- 使用Angular上载文件时,HttpPostedFileBase为null
- 文件输入更改时正在上载文件
- PhoneGap Ajax上载文件
- 如何使用$.ajax()上载文件
- 上载文件,但不能在表单中上载
- 正在使用getElementByClassName上载文件
- 通过本地文件路径上载文件
- 无法使用bootstrapValidator Ajax上载文件