How do you set the name of a blob file in JavaScript when force downloading it through window.location?

function newFile(data) { var json = JSON.stringify(data); var blob = new Blob([json], {type: "octet/stream"}); var url = window.URL.createObjectURL(blob); window.location.assign(url); } 

Running the above code downloads a file instantly without a page refresh that looks like:

bfefe410-8d9c-4883-86c5-d76c50a24a1d

I want to set the filename as my-download.json instead.

10 Answers

The only way I'm aware of is the trick used by FileSaver.js:

  1. Create a hidden <a> tag.
  2. Set its href attribute to the blob's URL.
  3. Set its download attribute to the filename.
  4. Click on the <a> tag.

Here is a simplified example (jsfiddle):

var saveData = (function () { var a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; return function (data, fileName) { var json = JSON.stringify(data), blob = new Blob([json], {type: "octet/stream"}), url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); window.URL.revokeObjectURL(url); }; }()); var data = { x: 42, s: "hello, world", d: new Date() }, fileName = "my-download.json"; saveData(data, fileName); 

I wrote this example just to illustrate the idea, in production code use FileSaver.js instead.

Notes

  • Older browsers don't support the "download" attribute, since it's part of HTML5.
  • Some file formats are considered insecure by the browser and the download fails. Saving JSON files with txt extension works for me.
20

I just wanted to expand on the accepted answer with support for Internet Explorer (most modern versions, anyways), and to tidy up the code using jQuery:

$(document).ready(function() { saveFile("Example.txt", "data:attachment/text", "Hello, world."); }); function saveFile (name, type, data) { if (data !== null && navigator.msSaveBlob) return navigator.msSaveBlob(new Blob([data], { type: type }), name); var a = $("<a style='display: none;'/>"); var url = window.URL.createObjectURL(new Blob([data], {type: type})); a.attr("href", url); a.attr("download", name); $("body").append(a); a[0].click(); window.URL.revokeObjectURL(url); a.remove(); } 

Here is an example Fiddle. Godspeed.

2

Same principle as the solutions above. But I had issues with Firefox 52.0 (32 bit) where large files (>40 MBytes) are truncated at random positions. Re-scheduling the call of revokeObjectUrl() fixes this issue.

function saveFile(blob, filename) { if (window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, filename); } else { const a = document.createElement('a'); document.body.appendChild(a); const url = window.URL.createObjectURL(blob); a.href = url; a.download = filename; a.click(); setTimeout(() => { window.URL.revokeObjectURL(url); document.body.removeChild(a); }, 0) } } 

jsfiddle example

2

Late, but since I had the same problem I add my solution:

function newFile(data, fileName) { var json = JSON.stringify(data); //IE11 support if (window.navigator && window.navigator.msSaveOrOpenBlob) { let blob = new Blob([json], {type: "application/json"}); window.navigator.msSaveOrOpenBlob(blob, fileName); } else {// other browsers let file = new File([json], fileName, {type: "application/json"}); let exportUrl = URL.createObjectURL(file); window.location.assign(exportUrl); URL.revokeObjectURL(exportUrl); } } 
10
saveFileOnUserDevice = function(file){ // content: blob, name: string if(navigator.msSaveBlob){ // For ie and Edge return navigator.msSaveBlob(file.content, file.name); } else{ let link = document.createElement('a'); link.href = window.URL.createObjectURL(file.content); link.download = file.name; document.body.appendChild(link); link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window})); link.remove(); window.URL.revokeObjectURL(link.href); } } 
2

This is my solution. From my point of view, you can not bypass the <a>.

function export2json() { const data = { a: '111', b: '222', c: '333' }; const a = document.createElement("a"); a.href = URL.createObjectURL( new Blob([JSON.stringify(data, null, 2)], { type: "application/json" }) ); a.setAttribute("download", "data.json"); document.body.appendChild(a); a.click(); document.body.removeChild(a); }
<button onclick="export2json()">Export data to json file</button>
0

Working example of a download button, to save a cat photo from an url as "cat.jpg":

HTML:

<button onclick="downloadUrl(' 'cat.jpg')">Download</button> 

JavaScript:

function downloadUrl(url, filename) { let xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.responseType = "blob"; xhr.onload = function(e) { if (this.status == 200) { const blob = this.response; const a = document.createElement("a"); document.body.appendChild(a); const blobUrl = window.URL.createObjectURL(blob); a.href = blobUrl; a.download = filename; a.click(); setTimeout(() => { window.URL.revokeObjectURL(blobUrl); document.body.removeChild(a); }, 0); } }; xhr.send(); } 
1

window.location.assign did not work for me. it downloads fine but downloads without an extension for a CSV file on Windows platform. The following worked for me.

 var blob = new Blob([csvString], { type: 'text/csv' }); //window.location.assign(window.URL.createObjectURL(blob)); var link = window.document.createElement('a'); link.href = window.URL.createObjectURL(blob); // Construct filename dynamically and set to link.download link.download = link.href.split('/').pop() + '.' + extension; document.body.appendChild(link); link.click(); document.body.removeChild(link); 

this is a good easy solution for it.

function downloadBloob(blob,FileName) { var link = document.createElement("a"); // Or maybe get it from the current document link.href = blob; link.download = FileName; link.click(); } 
1

If you want to download a pdf and using window.location is not mandatory, you can use jsPdf like this following :

// Create document const doc = new jsPDF('l', 'px', 'a4'); // [...] Add here the jsPdf doc filling // Launch the document downloading doc.output('save', 'filename.pdf'); 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy