Blob download is not working in IE
Asked Answered
D

11

49

I have this in my Angular.js controller that downloads a CSV file:

 var blob = new Blob([csvContent.join('')], { type: 'text/csv;charset=utf-8'});
 var link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
 link.href = URL.createObjectURL(blob);
 link.download = 'teams.csv';
 link.click();

This works perfectly in Chrome but not in IE. A browser console log says:

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.

What does it mean and how can I fix it?

Durham answered 1/12, 2013 at 9:25 Comment(2)
I have the same problem in IE with parallel.js.Normie
could you help me modifying my snippet the way you specified. jsfiddle.net/9gct9u78Sodium
H
82

Try this using, this or useragent

if (navigator.appVersion.toString().indexOf('.NET') > 0)
        window.navigator.msSaveBlob(blob, filename);
else
{
 var blob = new Blob(['stringhere'], { type: 'text/csv;charset=utf-8' });
 var link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
 link.href = URL.createObjectURL(blob);
 link.download = 'teams.csv';
 link.click();
}
Hyetograph answered 21/8, 2014 at 10:43 Comment(3)
+1. But to make it work in Firefox I had to add : document.body.appendChild(link); before the click() - and then remove the link again !Purgative
@PierreHenry or you make the link invisible by link.setAttribute('style','display:none');Bottali
It's not recommend to rely on navigator.appVersion (@see developer.mozilla.org/en-US/docs/Web/API/NavigatorID/appVersion) I would recommend to modify the if-statement to this: if (typeof(window.navigator.msSaveBlob) == 'function'){....Bottali
J
55

IE won't allow you to open blobs directly. You have to use msSaveOrOpenBlob. There's also msSaveBlob

if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
    var objectUrl = URL.createObjectURL(blob);
    window.open(objectUrl);
}
Jampan answered 28/1, 2017 at 19:49 Comment(2)
Perfect, This worked for me. I can now download the PDF in both Chrome and IE. ++1Endaendall
Perfect !! Worked for me.Gavin
D
20

I needed to use a Blob to download a converted a base64 PNG image. I was able to successfully download the blob on IE11 with window.navigator.msSaveBlob

See the following msdn link: http://msdn.microsoft.com/en-us/library/hh779016(v=vs.85).aspx

Specifically, you should call:

window.navigator.msSaveBlob(blobObject, 'msSaveBlob_testFile.txt');

where blobObject is a Blob created in the usual fashion.

Dowland answered 20/5, 2014 at 21:22 Comment(1)
or then for saving or opening the file in IE 11 or Egde: window.navigator.msSaveOrOpenBlob(blob, 'filename.pdf');Ophidian
N
11

Complete Solution for Chrome, Internet Explorer Firefox and Opera

There are lots of nice bits on this page, but I had to use a combination of a few things to get it all to work. Hopefully this helps you.

  1. Use a button or link to trigger a function called download():
<button class="button-no save-btn" ng-click="download()">DOWNLOAD</button>
  1. Put this in your controller:
$scope.download = function () {

    // example shows a JSON file
    var content = JSON.stringify($scope.stuffToPutInFile, null, "  ");
    var blob = new Blob([content], {type: 'application/json;charset=utf-8'});

    if (window.navigator && window.navigator.msSaveBlob) {

        // Internet Explorer workaround
        $log.warn("Triggering download using msSaveBlob");
        window.navigator.msSaveBlob(blob, "export.json");

    } else {
        
        // other browsers
        $log.warn("Triggering download using webkit");
        var url = (window.URL || window.webkitURL).createObjectURL(blob);
        
        // create invisible element
        var downloadLink = angular.element('<a></a>');
        downloadLink.attr('href', url);
        downloadLink.attr('download', 'export.json');
        
        // make link invisible and add to the DOM (Firefox)
        downloadLink.attr('style','display:none');
        angular.element(document.body).append(downloadLink);
        
        // trigger click
        downloadLink[0].click();
    }
};
Needless answered 11/4, 2019 at 16:20 Comment(1)
This worked awesome for mein IE, chrome, firefox and edge, thank youHinz
B
1

What's your IE browser version? You need a modern browser or IE10+ http://caniuse.com/bloburls

Bricklayer answered 31/7, 2014 at 2:28 Comment(0)
A
1

Maybe you need some delay. What about with:

link.click();
setTimeout(function(){
    document.body.createElementNS('http://www.w3.org/1999/xhtml', 'a');
    URL.revokeObjectURL(link.href);  
}, 100);
Acetanilide answered 2/11, 2016 at 18:27 Comment(0)
A
1

I needed to get the download feature to work in Chrome and IE11. I had good success with this code.

HTML

<div ng-repeat="attachment in attachments">
  <a ng-click="openAttachment(attachment)" ng-href="{{attachment.fileRef}}">{{attachment.filename}}</a>
</div>

JS

$scope.openAttachment = function (attachment) {
  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(
      b64toBlob(attachment.attachment, attachment.mimeType),
      attachment.filename
    );
  }
};
Annettannetta answered 16/5, 2018 at 18:19 Comment(0)
L
1

Done it this way, working fine for me.

downloadFile(data) {
    if (navigator.msSaveBlob) {
      let blob = new Blob([data], {
        "type": "text/csv;charset=utf8;"
      });
      navigator.msSaveBlob(blob, this.fileName);
    }
    else {
      let blob = new Blob(['\ufeff' + data], { type: 'text/csv;charset=utf-8;' });
      let $link = document.createElement("a");
      let url = URL.createObjectURL(blob);
      $link.setAttribute("target", "_blank");
      $link.setAttribute("href", url);
      $link.setAttribute("download", this.fileName);
      $link.style.visibility = "hidden";
      document.body.appendChild($link);
      $link.click();
      document.body.removeChild($link);
    }
  }
Lolly answered 5/9, 2018 at 9:32 Comment(0)
P
0

Try to use this instead : var blob = file.slice(0, file.size);

Phile answered 17/12, 2013 at 12:44 Comment(1)
See this Question / answser: #14206627Evieevil
C
0

Create polyfill method as below,had a variable filename since in my case download filename was static.This method will be called while blob function is not supported as in case of Internet explorer

    if (!HTMLCanvasElement.prototype.toBlob) {
            Object.defineProperty(HTMLCanvasElement.prototype, 
            'toBlob', {
                value: function (callback, type, quality) {
                var canvas = this;
                setTimeout(function () {
                var binStr = atob(canvas.toDataURL(type, quality).split(',')[1]),
                    len = binStr.length,
                    arr = new Uint8Array(len);

                for (var i = 0; i < len; i++) {
                    arr[i] = binStr.charCodeAt(i);
                }
                var blob = new Blob([arr], {
                    type: 'image/png'
                });
                window.navigator.msSaveOrOpenBlob(blob, fileName);
            });
        }
    });
}
Claritaclarity answered 19/5, 2020 at 15:20 Comment(0)
A
0
try {
      const blob = new Blob([res.body], {
        type: res.headers.get('Content-Type'),
      });
      const file = new File([blob], this.getFileName(res), {
        type: res.headers.get('Content-Type'),
      });

      saveAs(file);
    } catch (err) {
      var textFileAsBlob = new Blob([res.body], {
        type: res.headers.get('Content-Type'),
      });
      window.navigator.msSaveBlob(textFileAsBlob, this.getFileName(res));
    }

To get the file name. Use the below function.

getFileName(response: any) {
    let name: string;
    try {
      const contentDisposition: string = response.headers.get(
        'content-disposition'
      );
      const [, filename] = contentDisposition.split('filename=');
      name = filename;
    } catch (e) {
      name = 'File_Name_Not_Specified_' + new Date();
    }
    return name;
  }

This worked for me.

Adamsite answered 17/12, 2020 at 13:49 Comment(3)
new File() constructor is not working on iE11. is there any alternative solution for this ? to convert a blob file to File() type without using File constructor on IE11.Kazim
Refer this https://mcmap.net/q/356080/-saving-file-on-ie11-with-filesaver. Also check for other browser compatibility using this caniuse.com/?search=file.Adamsite
It was mentioned there to download or save file to local but what I need is to send that file to API request in File type format. just wondering is that actually possible on IE11 ?Kazim

© 2022 - 2024 — McMap. All rights reserved.