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?
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).
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.
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).
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 } } });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With