Prompt file download with XMLHttpRequest
download: function(){
var postData = new FormData();
var xhr = new XMLHttpRequest();
xhr.open('GET', downloadUrl, true);
xhr.responseType = 'blob';
xhr.onload = function (e) {
var blob = xhr.response;
this.saveOrOpenBlob(blob);
}.bind(this)
xhr.send(postData);
}
saveOrOpenBlob: function(blob) {
var assetRecord = this.getAssetRecord();
var fileName = 'Test.mp4'
var tempEl = document.createElement("a");
document.body.appendChild(tempEl);
tempEl.style = "display: none";
url = window.URL.createObjectURL(blob);
tempEl.href = url;
tempEl.download = fileName;
tempEl.click();
window.URL.revokeObjectURL(url);
},
Try this it is working for me.
UPDATE: this answer is not accurate anymore since the introduction of Blob API. Please refer to Steven's answer for details.
ORIGINAL ANSWER:
XHR request will not trigger file download. I can't find explicit requirement, but W3C doc on XMLHttpRequest doesn't describe any special reaction on content-disposition=attachment responses either
You could download file by window.open()
in separate tab, if it was not POST request. Here it was suggested to use a hidden form with target=_blank
If you set the XMLHttpRequest.responseType
property to 'blob'
before sending the request, then when you get the response back, it will be represented as a blob. You can then save the blob to a temporary file and navigate to it.
var postData = new FormData();
postData.append('cells', JSON.stringify(output));
var xhr = new XMLHttpRequest();
xhr.open('POST', '/export/', true);
xhr.setRequestHeader('X-CSRFToken', csrftoken);
xhr.responseType = 'blob';
xhr.onload = function (e) {
var blob = e.currentTarget.response;
var contentDispo = e.currentTarget.getResponseHeader('Content-Disposition');
// https://stackoverflow.com/a/23054920/
var fileName = contentDispo.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1];
saveOrOpenBlob(blob, fileName);
}
xhr.send(postData);
And here's an example implementation of saveOrOpenBlob
:
function saveOrOpenBlob(blob, fileName) {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fs) {
fs.root.getFile(fileName, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.addEventListener("writeend", function () {
window.location = fileEntry.toURL();
}, false);
fileWriter.write(blob, "_blank");
}, function () { });
}, function () { });
}, function () { });
}
If you don't care about having the browser navigate to the file when it's a viewable file type, then making a method that always saves directly to file is much simpler:
function saveBlob(blob, fileName) {
var a = document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.download = fileName;
a.dispatchEvent(new MouseEvent('click'));
}