Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle file download from ajax post

I have a javascript app that sends ajax POST requests to a certain URL. Response might be a JSON string or it might be a file (as an attachment). I can easily detect Content-Type and Content-Disposition in my ajax call, but once I detect that the response contains a file, how do I offer the client to download it? I've read a number of similar threads here but none of them provide the answer I'm looking for.

Please, please, please do not post answers suggesting that I shouldn't use ajax for this or that I should redirect the browser, because none of this is an option. Using a plain HTML form is also not an option. What I do need is to show a download dialog to the client. Can this be done and how?

like image 358
Pavle Predic Avatar asked Apr 18 '13 14:04

Pavle Predic


People also ask

How to download file from response in AJAX?

Downloading PDF File on Button Click using jQueryInside the DownloadFile JavaScript function, the URL of the File is passed as parameter to the jQuery AJAX function. Inside the jQuery AJAX function, using the XmlHttpRequest (XHR) call, the PDF file is downloaded as Byte Array (Binary Data).

How to download file from AJAX response in jQuery?

download-ss-btn', function () { $. ajax({ type: "POST", url: 'http://127.0.0.1:8080/utils/json/pdfGen', data: { data: JSON. stringify(jsonData) } }). done(function (data) { var blob = new Blob([data]); var link = document.

How do I download a file using JavaScript?

To ask the browser to download a file it can render, use the following header: Content-Disposition: attachment; filename="downloaded. pdf" (you can of course customize the filename as you need).


1 Answers

Don't give up so quickly, because this can be done (in modern browsers) using parts of the FileAPI:

var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.responseType = 'blob'; xhr.onload = function () {     if (this.status === 200) {         var blob = this.response;         var filename = "";         var disposition = xhr.getResponseHeader('Content-Disposition');         if (disposition && disposition.indexOf('attachment') !== -1) {             var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;             var matches = filenameRegex.exec(disposition);             if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');         }          if (typeof window.navigator.msSaveBlob !== 'undefined') {             // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."             window.navigator.msSaveBlob(blob, filename);         } else {             var URL = window.URL || window.webkitURL;             var downloadUrl = URL.createObjectURL(blob);              if (filename) {                 // use HTML5 a[download] attribute to specify filename                 var a = document.createElement("a");                 // safari doesn't support this yet                 if (typeof a.download === 'undefined') {                     window.location.href = downloadUrl;                 } else {                     a.href = downloadUrl;                     a.download = filename;                     document.body.appendChild(a);                     a.click();                 }             } else {                 window.location.href = downloadUrl;             }              setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup         }     } }; xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.send($.param(params, true)); 

Or if using jQuery.ajax:

$.ajax({     type: "POST",     url: url,     data: params,     xhrFields: {         responseType: 'blob' // to avoid binary data being mangled on charset conversion     },     success: function(blob, status, xhr) {         // check for a filename         var filename = "";         var disposition = xhr.getResponseHeader('Content-Disposition');         if (disposition && disposition.indexOf('attachment') !== -1) {             var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;             var matches = filenameRegex.exec(disposition);             if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');         }          if (typeof window.navigator.msSaveBlob !== 'undefined') {             // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."             window.navigator.msSaveBlob(blob, filename);         } else {             var URL = window.URL || window.webkitURL;             var downloadUrl = URL.createObjectURL(blob);              if (filename) {                 // use HTML5 a[download] attribute to specify filename                 var a = document.createElement("a");                 // safari doesn't support this yet                 if (typeof a.download === 'undefined') {                     window.location.href = downloadUrl;                 } else {                     a.href = downloadUrl;                     a.download = filename;                     document.body.appendChild(a);                     a.click();                 }             } else {                 window.location.href = downloadUrl;             }              setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup         }     } }); 
like image 143
Jonathan Amend Avatar answered Sep 20 '22 12:09

Jonathan Amend