I\'m aware that jQuery\'s ajax method cannot handle downloads, and I do not want to add a jQuery plugin to do this.
I want to know how to send POST data with XMLHttp
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 hidden form with target=_blank
UPD: this answer is not accurate anymore since the introduction of Blob API. Please refer to Steven's answer for details.
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.
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 (this, event) {
var blob = this.response;
var contentDispo = this.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'));
}