当管道破裂时如何处理AJAX响应?
我有一个(
Spring Boot 1.5)REST服务器处理文件上传(multipart / form-data)和一个使用jQuery fileupload的JS客户端.在大多数情况下它工作正常,但是当我想上传一个更大的文件(大约4MB)时,服务器会发现它超出了限制并发回包含错误消息的响应.
但是,似乎服务器停止读取请求(当然是正确的),这导致客户端管道损坏.在这种情况下,不处理响应.使用以下data.jqXHR(data.response未定义)调用失败回调: {"readyState":0,"responseText":"","status":0,"statusText":"error"} 使用curl进行调用时,结果为: HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 curl: (55) Send failure: Broken pipe {"files":[{"size":3863407,"error":"upload_uploadSizeExceeded"}]} 因此返回了一个响应,但JS客户端似乎忽略了它.有没有选项让jQuery处理响应,即使请求只是部分发送? BTW:更奇怪的是,我在服务器日志中看到这样的请求多次重复这种情况,也许是JS中的一种重试机制?
简答 不,浏览器使用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('foobyn'); }).listen(8080); 客户测试 方法1:XMLHttpRequests 我仔细检查了每个事件,没有发送字节的指示.如果我们确实有一个Sent字节值,应该加载,我们可以知道请求是否在中途被取消以处理这种情况而没有响应: 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 specification:
方法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 Documentation Fetch Specification 浏览器不会将此视为HTTP错误,而是网络错误,因此不会转发与用户代码相关的任何HTTP. 结论 XHR和Fetch规范声明网络错误作为空响应处理. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |