Is there any option to make jQuery handle the response even if the
request is sent only partially?
Short Answer
No, browsers use XMLHttpRequest and Fetch API, and this is considered a network error, by the specification, and network errors are intentionally empty.
CURL does not handle responses according to XMLHttpRequest specification.
Long Answer
Simulated Server
Read the request's ReadableStream and cancel mid-way:
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);
Client Tests
Method 1: XMLHttpRequests
I carefully inspected each event and there is no indication of Sent bytes. If we did have a Sent bytes value, which should be in loaded
, we could know if the request was cancelled midway to handle this case without the response:
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));
Unfortunately, nothing.
The read-only XMLHttpRequest.status property returns the numerical
status code of the response of the XMLHttpRequest. status will be an
unsigned short. Before the request is complete, the value of status
will be 0. It is worth noting that browsers report a status of 0 in
case of XMLHttpRequest errors too.
From the XMLHttpRequest specification:
A response whose type is "error" is known as a network error.
A network error is a response whose status is always 0, status message
is always the empty byte sequence, header list is always empty, body
is always null, and trailer is always empty.
Method 2: Fetch API
I was hoping to intercept a low-level ReadableStream and get something, but, unfortunately, the resolve callback is not called on network errors:
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);
});
A fetch() promise rejects with a TypeError when a network error is
encountered, although this usually means a permissions issue or
similar. An accurate check for a successful fetch() would include
checking that the promise resolved, then checking that the Response.ok
property has a value of true. An HTTP status of 404 does not
constitute a network error.
Fetch Documentation
Fetch Specification
Browsers do not treat this as an HTTP error, but a network error, and therefore do not forward anything HTTP related to user code.
Conclusion
XHR and Fetch specification states that network errors are handled as empty responses.