An HTML5 saveAs() FileSaver implementation

Overview

If you need to save really large files bigger than 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

FileSaver.js

FileSaver.js is the solution to saving files on the client-side, and is perfect for web apps that generates files on the client, However if the file is coming from the server we recommend you to first try to use Content-Disposition attachment response header as it has more cross-browser compatiblity.

Looking for canvas.toBlob() for saving canvases? Check out canvas-toBlob.js for a cross-browser implementation.

Supported 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 2GB None
Chrome for Android Blob Yes RAM/5 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
Safari 10.1+   Blob         Yes         n/a           None

Feature detection is possible:

try {
    var isFileSaverSupported = !!new Blob;
} catch (e) {}

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 WebKit bug is affecting you.

Syntax

Import saveAs() from file-saver

import { saveAs } from 'file-saver';
FileSaver saveAs(Blob/File/Url, optional DOMString filename, optional Object { autoBom })

Pass { autoBom: true } if you want FileSaver.js to automatically provide Unicode text encoding hints (see: byte order mark). Note that this is only done if your blob type has charset=utf-8 set.

Examples

Saving text using require()

var FileSaver = require('file-saver');
var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "hello world.txt");

Saving text

var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "hello world.txt");

Saving URLs

FileSaver.saveAs("https://httpbin.org/image", "image.jpg");

Using URLs within the same origin will just use a[download]. Otherwise, it will first check if it supports cors header with a synchronous head request. If it does, it will download the data and save using blob URLs. If not, it will try to download it using a[download].

The standard W3C File API Blob interface is not available in all browsers. Blob.js is a cross-browser Blob implementation that solves this.

Saving a canvas

var canvas = document.getElementById("my-canvas");
canvas.toBlob(function(blob) {
    saveAs(blob, "pretty image.png");
});

Note: The standard HTML5 canvas.toBlob() method is not available in all browsers. canvas-toBlob.js is a cross-browser canvas.toBlob() that polyfills this.

Saving File

You can save a File constructor without specifying a filename. If the file itself already contains a name, there is a hand full of ways to get a file instance (from storage, file input, new constructor, clipboard event). If you still want to change the name, then you can change it in the 2nd argument.

// Note: Ie and Edge don't support the new File constructor,
// so it's better to construct blobs and use saveAs(blob, filename)
var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(file);

Tracking image

Installation

# Basic Node.JS installation
npm install file-saver --save
bower install file-saver

Additionally, TypeScript definitions can be installed via:

# Additional typescript definitions
npm install @types/file-saver --save-dev
Comments
  • Problems saving in iOS Safari

    Problems saving in iOS Safari

    Edit by @eligrey: Please tell Apple how this bug is affecting you in https://bugs.webkit.org/show_bug.cgi?id=102914 if you want this fixed.

    Edit by @jimmywarting The safari bug #102914 has been marked as fixed now

    according to the commit position, download attribute is fixed in WebKit v602.1.27. The latest beta build (Safari Technology Preview) is based on WebKit v602.1.25, and of course doesn't contain this patch, so there's no simple way to test.

    In the meantime, if you want to support Safari 7, you'll probably want to use Downloadify (uses Flash, not HTML5).


    Issues we have had with Safari

    • [x] Blob is not supported
      This has been solved with Blob.js using BlobBuilder as fallback and then base64 data uri if that are not supported either
    • [x] URL.createObjectUrl
      Has been covered by both FileSaver.js and blob.js Blob.js overrule createObjectUrl with it's own base64 url constructor only if it's a "fake blob" (i.e not a File or Blob representation) it will use window.URL, fallback to window.webkitURL or use it's own base64 function to create those "fake blobs" data-uri
    • [ ] The "can't open blob url" issue (partly supported) - screenshot

                The page you opened redirected you to a page that isn't supported by safari
    Safari can't open the page becuse Safari can't be redirected to address that begin with "blob:".

    • This is mostly cased by unsupported mime type, Safari do support opening blob url, but only if it's a mimetype that safari can understand like simple plain/text or a common image like image/png.
      • This will result in a new tab from which the user can just hit +S to save it
    • ATM FileSaver.js looks at the mimetype to see if it is application/octet-stream (wish is commonly used to force saving files from the server)
      If it's then it read the blob as base64 using FileReader to open a data:attachment/file" + base64 url in order to save it.
      • It's not possible to create a blob with attachment/file type directly and open it, then you will get errors like this: Failed to load resource: Frame load interrupted it has to be base64 for some reason...
      • the resulting filename will be "unknown" when doing this
    • [ ] The blank page error partial supported - (formuly known as "can't open blob url", see above)
      This can easily be reproduced by doing:
    window.onclick = function(){
        var blob = new Blob(["Hi"], {type: 'application/octet-stream'});
        var url = URL.createObjectURL(url);
        window.open(url);
    }
    

    If you replace window.open with location.href = you will get the Failed to load resource: Frame load interrupted and be unable to save the file that is not the case for all mimetype, mimetypes that Safari can display can be opened this way

    A little side note here is that window.open only works on trusted events meaning:

    • It will only be able to open the url when user interacts with the website like a onclick event (more about isTrusted event here - almost pointless becuse browser support)

    I have also found out that the trusted event persist for 1000 ms, so you could do:

    window.onclick = function(){
        setTimeout(function(){
            var blob = new Blob(["Hi"], {type: 'application/octet-stream'});
            var url = URL.createObjectURL(url);
            window.open(url);
        }, 950); // Any longer then 1sec will make the window.open blocked again
    }
    

    So the conclusion here about safari is

    1. download attribute in safari is not supported
    2. It will try other means to save the blob by opening a new url
    3. If the mimetype can be rendered by safari it will be able to display it in a new tab
    4. If the mimetype is application/octet-stream:
      4.1 Create a base64 link with FileReader api
      4.2 try to open a new tab using window.open + base64 url
      4.3 if it was more then 1 sec before the user interaction happened it will use the current page instead
      but that is likely going to fail because (see first example using location.href) Failed to load resource: Frame load interrupted This may still work if the mimetype is not application/octet-stream and the saveAs was not called synchronous
    5. Safari don't have anything like msSaveAs()
    6. safest way to force the file to be saved is to have a data:attachment/file" + base64 ready and open that link using window.open() when the user interacts with the website (or at least to it under 1 second)
    7. when saving it as a attachment filename will be "unknown"
    safari 
    opened by gawry 175
  • Help needed in using fileSaver.js with Angular 2 app

    Help needed in using fileSaver.js with Angular 2 app

    I am trying to use fileSaver.js with angular 2 , but am not able to import the module

    i am getting cannot find file-saver module error .

    Any help is appreciated

    opened by deephakdd 41
  • Is IOS Safari working with FileSaver.js?

    Is IOS Safari working with FileSaver.js?

    Hi, From the demo website it was failed to download by pressing the save button with IOS safari. It just open in a new tab and showing blob url.

    Following the documentation, tried using on-click, but seem doesn't work as well.

    Anyone could advise? Thanks a lot.

    opened by dodomui 39
  • saving Zip file problems

    saving Zip file problems

    Hi I have been using FileSaver.js with no problems to save binary data generated in browser, but am having problems with the following code:

    console.log(myData.length); // yields 13292 - which is the correct data length
    var blob = new Blob([myData], {type: "application/zip"});
    console.log(blob.size); // yields 13404
    saveAs(blob, "data.zip"); 
    

    Note the difference in lengths. The result is that the zip file will not unpack correctly. myData is a string containing binary data. I have also tried reading it into an array first, various different mime types (none, text, octet-stream). Any ideas?

    opened by jvsteiner 32
  • Saving an UTF-8 Excel blob

    Saving an UTF-8 Excel blob

    I'm trying to save a Blob of an Excel file, but the saved file is large double than the original, and Excel says it's corrupted.

    var data // = data from AJAX response, 6854 bytes
    var type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
    var blob = new Blob( [ data ], { type: type } );
    FileSaver.saveAs(blob, "file.xlsx");
    

    Chrome opens the file download modal, but the saved file is 11953 bytes large and Excel says it's corrupted.

    Make a Blob 
    opened by heruan 30
  • Saving huge files ( 2GB + )

    Saving huge files ( 2GB + )

    I would like to implement, if possible , a multi-connection downloader in HTML5.. To do that for extremely large files , it needs to download in chunks and join them in a whole file afterwards.

    Problem is > you obviously cannot store that much information in RAM ..

    1.) How would you go about doing that ? is it even possible ? 2.) Would resume support be possible on browser crash ?

    Thanks !

    opened by DannyZB 27
  • Android chrome download issue

    Android chrome download issue

    Looks like there is a weird download issue in chrome on android. If you click on save and hit download it throws an error message as shown below "was not able to download the file because of an unknown issue".

    Weird thing, the image has been actually saved and can be opened through the download list.

    Chrome ver.: 58.0.3029.83 Android ver.: 7.0.0

    0-weu-d1-fbcb6b6b9863ef6adcf9d419a0f7f1af

    chrome Android 
    opened by maertz 23
  • module export changed from 1.3.3 to 1.3.4

    module export changed from 1.3.3 to 1.3.4

    I used FileSaver 1.3.3 with webpack and react+redux for quite a while. It works like magic!

    However, currently I tried to upgrade it to 1.3.4 and found there's a module changes that cause major problems between the versions.

    Previously, this syntax work in react-webpack to import and use FileSaver

    import FileSaver from "file-saver"
    
    FileSaver.saveAs(blob, "filename.pdf")
    

    after 1.3.4, it has to be like this

    import FileSaver from "file-saver"
    
    FileSaver(blob, "filename.pdf")
    

    I suggest changing main API like this should be done in major version like going upward to 1.4.0 instead of minor version 1.3.3->1.3.4

    since this will affect those who has

    "file-saver": "^1.3.3",
    

    like this in package.json. NPM will auto increment the version in the later build

    Thanks!

    opened by puttpotsawee 22
  • Saving CSV with unique chars using in a different encoding other than UTF-8

    Saving CSV with unique chars using in a different encoding other than UTF-8

    This is not exactly an issue, rather it is a solution ( for example a solution to: https://github.com/eligrey/FileSaver.js/issues/25 )

    Solution: For all your special character needs, just use UTF-8, but additionally add a BOM to make sure the file is opened correctly. CSV for example was opened by Office Excel versions prior to Office 2007 with the wrong ANSI 1252 encoding by default. Adding a BOM will make the file open correctly (in UTF-8) in Office versions since Office 2007 (maybe needs Office SP for Office 2007)

    var BOM = "\uFEFF";
    var    csvData = BOM + csvData;
    var blob = new Blob([csvData], { type: "text/csv;charset=utf-8" });
    saveAs(blob, "myFile.csv");
    
    opened by ranabra 21
  • Chrome 65 : Can't open same-window link to

    Chrome 65 : Can't open same-window link to "blob:

    It seems that the latest update to Chrome (65) has lead to the window.saveAs() to fail in Chrome Extensions or Packaged Apps .

    The error helpfully suggest try target="_blank".

    Do you know if we can pass a target to saveAs ?

    opened by simonaberry 19
  • Safari : Failed to load resource: Frame load interrupted

    Safari : Failed to load resource: Frame load interrupted

    OSx: 10.11.3 (15D21) Safari: Version 9.0.3 (11601.4.4)

    If I want to download something as a file, my browser console logs:

    Failed to load resource: Frame load interrupted

    It looks like your demo (https://eligrey.com/demos/FileSaver.js/ --> Saving rich text) has the same issue.

    bug safari 
    opened by dimfried 18
  • IPhone/Opera:

    IPhone/Opera: "Opera cannot open the page because the address is invalid"

    Hi,

    Steps to reproduce

    • On an iPhone, visit https://stackblitz.com/edit/file-saver-zke5nx with the Opera browser
    • Click on the "Download PDF" button.

    Current behavior Opera shows the "Opera cannot open the page because the address is invalid" error: Captura de pantalla 2022-12-19 a las 18 33 39

    Expected behavior Opera downloads the pdf

    Thanks for your work 🙏

    opened by aleixsuau 0
  • Bump decode-uri-component from 0.2.0 to 0.2.2

    Bump decode-uri-component from 0.2.0 to 0.2.2

    Bumps decode-uri-component from 0.2.0 to 0.2.2.

    Release notes

    Sourced from decode-uri-component's releases.

    v0.2.2

    • Prevent overwriting previously decoded tokens 980e0bf

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.1...v0.2.2

    v0.2.1

    • Switch to GitHub workflows 76abc93
    • Fix issue where decode throws - fixes #6 746ca5d
    • Update license (#1) 486d7e2
    • Tidelift tasks a650457
    • Meta tweaks 66e1c28

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.1

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Progress of downloading zip file from s3 presigned url not showing in browsers

    Progress of downloading zip file from s3 presigned url not showing in browsers

    Hi all! I'm using a file-saver to save a zip-files from an s3 presigned url - I get a blob from a request and pass it to a file-saver with a custom filename. Now, after the download starts, the file is downloaded in the background and only after the download is completed it immediately appears in the browser download list (and at the bottom panel of Google Chrome f.e.). But I just want to see the progress of downloading the file immediately after the download starts (with the remaining time and the total file size as in the bottom bar, usual for Google Chrome). According to this guide https://github.com/eligrey/FileSaver.js/wiki/Saving-a-remote-file#using-http-header I added 'Content-Disposition: attachment; filename=some-name.zip' header in s3 presigned url response but it didn't help. I haven't tried other options from this guide as they look like a crutch. But I can be wrong. What am I doing wrong? What could be the issue? Should I try a different approach? I'll be appreciate for any help.

    opened by and-zverev 5
  • Console log an error when saveAs is called from a web worker

    Console log an error when saveAs is called from a web worker

    Currently if you try to run saveAs from a web worker, it fails silently. Instead we should send an error to the console to communicate that saveAs can only be called from the main thread.

    Fixes https://github.com/eligrey/FileSaver.js/issues/778.

    opened by TheBatmanofButler 0
  • saveAs fails on chrome with no error

    saveAs fails on chrome with no error

    Thanks for this library.

    I'm getting silent failures where, when I try to download using saveAs, it fails without any error or log -- a download simply never appears.

    I'm using Chrome: Version 107.0.5304.87 (Official Build) (64-bit), on Ubuntu 20.02.

    Any idea whats going on?

    Example code:

    import {saveAs} from 'file-saver'
    
    const blob = new Blob(['helloworld'], {
      type: "application/json",
    });
    
    saveAs(blob, 'test')
    
    opened by theahura 2
Releases(v2.0.4)
Owner
Eli Grey
Full-stack web developer and offensive security researcher.
Eli Grey
An in-depth implementation of Clean Architecture using NestJS and type-script

Clean Architecture With NestJS Description It's been a while since my last article on how to implement clean architecture on Node.js applications, git

null 297 Dec 28, 2022
WASM-based implementation of Cloudflare's HTML Rewriter for use in Deno, browsers, etc.

HTML Rewriter WASM-based implementation of Cloudflare's HTML Rewriter for use in Deno, browsers, etc. It uses lol-html under the hood, the same implem

Worker Tools 36 Dec 6, 2022
HTML5 Canvas Gauge. Tiny implementation of highly configurable gauge using pure JavaScript and HTML5 canvas. No dependencies. Suitable for IoT devices because of minimum code base.

HTML Canvas Gauges v2.1 Installation Documentation Add-Ons Special Thanks License This is tiny implementation of highly configurable gauge using pure

Mykhailo Stadnyk 1.5k Dec 30, 2022
Responsive, interactive and more accessible HTML5 canvas elements. Scrawl-canvas is a JavaScript library designed to make using the HTML5 canvas element a bit easier, and a bit more fun!

Scrawl-canvas Library Version: 8.5.2 - 11 Mar 2021 Scrawl-canvas website: scrawl-v8.rikweb.org.uk. Do you want to contribute? I've been developing thi

Rik Roots 227 Dec 31, 2022
HTML5

One file. Any browser. Same UI. Author: John Dyer http://j.hn/ Website: http://mediaelementjs.com/ License: MIT Meaning: Use everywhere, keep copyrigh

MediaElement.js 8k Dec 27, 2022
Open source rich text editor based on HTML5 and the progressive-enhancement approach. Uses a sophisticated security concept and aims to generate fully valid HTML5 markup by preventing unmaintainable tag soups and inline styles.

This project isn’t maintained anymore Please check out this fork. wysihtml5 0.3.0 wysihtml5 is an open source rich text editor based on HTML5 technolo

Christopher Blum 6.5k Jan 7, 2023
Open source rich text editor based on HTML5 and the progressive-enhancement approach. Uses a sophisticated security concept and aims to generate fully valid HTML5 markup by preventing unmaintainable tag soups and inline styles.

This project isn’t maintained anymore Please check out this fork. wysihtml5 0.3.0 wysihtml5 is an open source rich text editor based on HTML5 technolo

Christopher Blum 6.5k Dec 30, 2022
HTML5

One file. Any browser. Same UI. Author: John Dyer http://j.hn/ Website: http://mediaelementjs.com/ License: MIT Meaning: Use everywhere, keep copyrigh

MediaElement.js 8k Jan 8, 2023
An HTML5/Canvas implementation of 8-bit color cycling

Overview Here is the JavaScript and C++ source code to my color cycling engine, written in 2010. I am releasing it under the LGPL v3.0. The package co

Joseph Huckaby 8 Dec 1, 2022
An implementation of Bézier curve rendering and manipulation, using the HTML5 Canvas API.

Bézier Curves An implementation of Bézier curve rendering and manipulation, using the HTML5 Canvas API. How does it work? Bézier curves can be simply

nethe550 1 Apr 13, 2022
This is a template project demonstrating how the MERN stack(Mongo, Express, React, Node) can be used, here we have the back end implementation and there is the React implementation as the front end

Versão em português MERN stack This is a template project demonstrating how the MERN stack(Mongo, Express, React, Node) can be used, here we have the

Douglas Samuel Gonçalves 2 Jan 22, 2022
Simple HTML5 Charts using the tag

Simple yet flexible JavaScript charting for designers & developers Documentation Currently, there are two versions of the library (2.9.4 and 3.x.x). V

Chart.js 59.4k Jan 7, 2023
The Swiss Army Knife of Vector Graphics Scripting – Scriptographer ported to JavaScript and the browser, using HTML5 Canvas. Created by @lehni & @puckey

Paper.js - The Swiss Army Knife of Vector Graphics Scripting If you want to work with Paper.js, simply download the latest "stable" version from http:

Paper.js 13.5k Dec 30, 2022
🔥 JavaScript Library for HTML5 canvas based heatmaps

heatmap.js Dynamic Heatmaps for the Web. How to get started The fastest way to get started is to install heatmap.js with bower. Just run the following

Patrick Wied 5.9k Jan 2, 2023
Dynamic HTML5 visualization

Envision.js Fast interactive HTML5 charts. http://groups.google.com/group/envisionjs/ Features Modern Browsers, IE 6+ Mobile / Touch Support Pre-built

HumbleSoftware 1.6k Dec 3, 2022
Financial lightweight charts built with HTML5 canvas

Lightweight Charts Demos | Documentation | Discord community TradingView Lightweight Charts are one of the smallest and fastest financial HTML5 charts

TradingView, Inc. 5.8k Jan 9, 2023
Mini projects built with HTML5, CSS & JavaScript. No frameworks or libraries

20+ Web Projects With Vanilla JavaScript This is the main repository for all of the projects in the course. Course Link Course Info Website # Project

Brad Traversy 14.1k Jan 4, 2023
Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js.

Onsen UI - Cross-Platform Hybrid App and PWA Framework Onsen UI is an open source framework that makes it easy to create native-feeling Progressive We

null 8.7k Jan 8, 2023
Konva.js is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.

Konva Konva is an HTML5 Canvas JavaScript framework that enables high performance animations, transitions, node nesting, layering, filtering, caching,

konva 8.7k Jan 8, 2023
Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js.

Onsen UI - Cross-Platform Hybrid App and PWA Framework Onsen UI is an open source framework that makes it easy to create native-feeling Progressive We

null 8.7k Jan 4, 2023