是否有任何选项可以让 jQuery 处理响应,即使
请求只发送了一部分?
简答
不,浏览器使用 XMLHttpRequest 和 Fetch API,这被规范认为是网络错误,网络错误是故意为空的。
CURL 不根据 XMLHttpRequest 规范处理响应。
长答案
模拟服务器
读取请求的 ReadableStream 并中途取消:
const http = require('http');
const server = http.createServer((req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Content-Type', 'text/plain');
//Close Request ReadableStream Prematurely
//to simulate close pipe on exceed file size
if (req.url === '/data' && req.method === 'POST') {
console.log('simulating...');
let i = 0;
req.on('data', chunk => {
if (i++ === 10)
req.destroy('broken pipe');
});
}
res.end('fooby\n');
}).listen(8080);
客户端测试
方法一:XMLHttpRequests
我仔细检查了每个事件,没有任何已发送字节的迹象。如果我们确实有一个 Sent bytes 值,它应该在 loaded 中,我们可以知道请求是否在中途被取消以处理这种情况而没有响应:
let req = new XMLHttpRequest();
req.open('POST', 'http://localhost:8080/data');
req.onloadstart = function (event) {
console.log(event);
};
req.onprogress = function (event) {
console.log(event);
};
req.onabort = function (event) {
console.log(event);
};
req.onerror = function (event) {
console.log(event);
};
req.onload = function (event) {
console.log(event);
};
req.ontimeout = function (event) {
console.log(event);
};
req.onloadend = function (event) {
console.log(event);
};
req.onreadystatechange = function (event) {
console.log(event);
};
req.send(new ArrayBuffer(100000000));
很遗憾,什么都没有。
只读 XMLHttpRequest.status 属性返回数值
XMLHttpRequest 响应的状态码。状态将是
无符号短。在请求完成之前,status的值
将为 0。值得注意的是,浏览器在
XMLHttpRequest 错误的情况。
来自XMLHttpRequest specification:
类型为“错误”的响应称为网络错误。
网络错误是状态始终为 0 的响应,状态消息
始终为空字节序列,头列表始终为空,正文
始终为 null,并且预告片始终为空。
方法2:获取API
我希望拦截一个低级别的 ReadableStream 并得到一些东西,但不幸的是,在网络错误时没有调用解析回调:
fetch('http://localhost:8080/data', {
method: 'POST',
body: new ArrayBuffer(100000000),
mode: 'cors'
}).then(resp => {
console.log(resp);
//hopefully we can get readable stream here
//...nope, networkerrors do not trigger resolve
}).catch(error => {
console.log(error);//TypeError: "NetworkError when attempting to fetch resource."
}).then(retry => {
console.log(retry);
});
当出现网络错误时,fetch() 承诺会以 TypeError 拒绝
遇到,尽管这通常意味着权限问题或
相似的。对成功 fetch() 的准确检查将包括
检查承诺是否已解决,然后检查 Response.ok
属性的值为 true。 HTTP 状态 404 不会
构成网络错误。
Fetch Documentation
Fetch Specification
浏览器不会将此视为 HTTP 错误,而是网络错误,因此不会转发任何与用户代码相关的 HTTP。
结论
XHR 和 Fetch 规范规定网络错误作为空响应处理。