I am using XMLHttpRequest (Level 2) to upload a file to a node.js server. I am checking the file-stream for the valid header on the server side. Now I want to trigger a cancellation of the upload if there are any errors while streaming. My XMLHttpRequest code is very simple:
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);
});
On the server side I am piping the req stream through my validator into a file stream. I want the XMLHttpRequest to abort the upload if any errors occur while validating. But just sending a 400 as response to the request doesn't work at all. I registered all kinds of listeners to the xhr but none of them fire. It doesn't seem to care about the 400 at all and still tries to upload the file. Normally I would expect that the onreadystatechange event would fire on this occasion.
I tried closing the req by issuing an req.end() but that seems a bit harsh and reveals another curiosity. If I do that, the XMLHttpRequest retries to send the POST request exactly 7 times (in Chrome; 5 times in Firefox; is this documented anywhere?).
Edit: As Paul suggested:
...connection close before receiving any status from the server...
On the server side I try to listen to the finish event of the response.
checkedFile.on('error', function (err) {
res.status(400);
res.end();
});
res.on('finish', function () {
req.destroy();
});
But it retries anyway. I just doesn't care about the 400.
Maybe there is another way of canceling without destroying the request stream?
Second edit: It is possible to end the request without destroying the request stream:
checkedFile.on('wrong', function (err) {
checkedFile.end();
res.writeHead(400, { 'Connection': 'close' });
res.end();
});
But the XHR is still retrying the request.