How to create a file and generate a download with Javascript in the Browser (without a server)


Generate and download a file using Javascript ? If you think about it, this isn't so secure as you think and shouldn't be allowed without the user interaction (however now is allowed).

Imagine that you use Google Chrome and you have enabled the option "Auto-open downloaded files", and for your bad luck you enter in a malicious website and it generates the download of an unknown file. You know how this story ends.

However, in the latest browsers unknow or rare downloaded file extensions are blocked and a prompt appears if you really want to open that file (at less in Chrome).

Therefore, the automatic download of file has been difficult to achieve in the latest years, but now with the introduction of HTML5, this task has become easier to achieve.

In this article we are going to show you a couple of tricks to generate and download directly a file using pure Javascript.

Self-implemented download function

The following simple function allow you to generate a download of a file directly in the browser without contact any server. It works on all HTML5 Ready browsers as it uses the download attribute of the <a> element:

function download(filename, text) {
  var element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
}

// Start file download.
download("hello.txt","This is the content of my file :)");

The download attribute specifies that the target will be downloaded when a user clicks on the hyperlink. This attribute is only used if the href attribute is set.

You can see this snippet in action in the following fiddle:

Using a library

Make libraries, not the war. FileSaver.js implements the saveAs() FileSaver interface in browsers that do not natively support it.

If you need to save really large files bigger then the blob's size limitation or don't have enough RAM, then have a look at the more advanced StreamSaver.js that can save data directly to the hard drive asynchronously with the power of the new streams API. That will have support for progress, cancelation and knowing when it's done writing.

The following snippet allow you to generate a file (with any extension) and download it without contact any server :

var content = "What's up , hello world";
// any kind of extension (.txt,.cpp,.cs,.bat)
var filename = "hello.txt";

var blob = new Blob([content], {
 type: "text/plain;charset=utf-8"
});

saveAs(blob, filename);

The following table shows the compatibility of FileSaver.js in different browsers:

Browser Constructs as Filenames Max Blob Size Dependencies
Firefox 20+ Blob Yes 800 MiB None
Firefox < 20 data: URI No n/a Blob.js
Chrome Blob Yes 500 MiB None
Chrome for Android Blob Yes 500 MiB None
Edge Blob Yes ? None
IE 10+ Blob Yes 600 MiB None
Opera 15+ Blob Yes 500 MiB None
Opera < 15 data: URI No n/a Blob.js
Safari 6.1+* Blob No ? None
Safari < 6 data: URI No n/a Blob.js

Note: although it supports the most recent browsers, there are a couple of trick that you need to know to provide full support.

IE < 10

It is possible to save text files in IE < 10 without Flash-based polyfills. See ChenWenBrian and koffsyrup's saveTextAs() for more details.

Safari 6.1+

Blobs may be opened instead of saved sometimes—you may have to direct your Safari users to manually press ?+S to save the file after it is opened. Using the application/octet-stream MIME type to force downloads can cause issues in Safari.

iOS

saveAs must be run within a user interaction event such as onTouchDown or onClick; setTimeout will prevent saveAs from triggering. Due to restrictions in iOS saveAs opens in a new window instead of downloading, if you want this fixed please tell Apple how this bug is affecting you.

Have fun !

Become a more social person