Download attribute on A tag not working in IE
Asked Answered
H

9

50

From the following code I'm creating a dynamic anchor tag which downloads a file. This code works well in Chrome but not in IE. How can I get this working

<div id="divContainer">
    <h3>Sample title</h3>
</div>
<button onclick="clicker()">Click me</button>

<script type="text/javascript">

    function clicker() {
        var anchorTag = document.createElement('a');
        anchorTag.href = "http://cdn1.dailymirror.lk/media/images/finance.jpg";
        anchorTag.download = "download";
        anchorTag.click();


        var element = document.getElementById('divContainer');
        element.appendChild(anchorTag);
    }

</script>
Hageman answered 23/8, 2013 at 4:47 Comment(3)
Why do you bother appendChild it when you click it first? Ad why click it when you can do location=URLLength
I see no point in creating a new a tag. Why dont you trigger the download when you click the click me button. Web users dont like to clickHumidifier
For reference caniuse.com/#feat=downloadUnsociable
P
35

Internet Explorer does not presently support the Download attribute on A tags.

See http://caniuse.com/download and http://status.modern.ie/adownloadattribute; the latter indicates that the feature is "Under consideration" for IE12.

Portecochere answered 23/8, 2013 at 16:52 Comment(7)
So there's no workaround to set the file name in IE?Chamber
Your question is insufficiently precise. The file-delivering server chooses the filename.Portecochere
I've found a workaround for this in IE, instead of creating an <a> tag. just use this one line...navigator.msSaveBlob(blob, fileName); Credit to download.js for the following line: github.com/rndme/download/blob/master/download.js#L143Error
2017 Still no IE12... This feature is supported in Edge, though.Binturong
@AllenRufolo IE12 = Edge... at least the first version of EdgeInterrupted
This does not answer the question of "How can I get this working"Gottwald
@Error Thank you so much for your comment, if you had this as an answer, I would up-vote. This saved me a lot of head acheSlight
T
31

In my case, since there's a requirement to support the usage of IE 11 (version 11.0.9600.18665), I ended up using the solution provided by @Henners on his comment:

// IE10+ : (has Blob, but not a[download] or URL)
if (navigator.msSaveBlob) {
    return navigator.msSaveBlob(blob, fileName);
}

It's quite simple and practical.

Apparently, this solution was found on the Javascript download function created by dandavis.

Teleplay answered 31/5, 2017 at 14:28 Comment(2)
I tried this and get blob is undefined. Can you explain how to define blob and what to put in it. I just have the URL of the file. Is there a way to load a file into a blob from the URL?Reprise
Perhaps this answer can help you to achieve the conversion you want. Afterwards, you just need to trigger the download as mentioned in my answer.Recuperator
M
15

Old question, but thought I'd add our solution. Here is the code I used on my last project. It's not perfect, but it passed QA in all browsers and IE9+.

downloadCSV(data,fileName){
  var blob = new Blob([data], {type:  "text/plain;charset=utf-8;"});
  var anchor = angular.element('<a/>');

  if (window.navigator.msSaveBlob) { // IE
    window.navigator.msSaveOrOpenBlob(blob, fileName)
  } else if (navigator.userAgent.search("Firefox") !== -1) { // Firefox
    anchor.css({display: 'none'});
    angular.element(document.body).append(anchor);

    anchor.attr({
      href: 'data:attachment/csv;charset=utf-8,' + encodeURIComponent(data),
      target: '_blank',
      download: fileName
    })[0].click();

    anchor.remove();
  } else { // Chrome
    anchor.attr({
      href: URL.createObjectURL(blob),
      target: '_blank',
      download: fileName
    })[0].click();
  }
}

Using the ms specific API worked best for us in IE. Also note that some browsers require the anchor to actually be in the DOM for the download attribute to work, whereas Chrome, for example, does not. Also, we found some inconsistencies with how Blobs work in various browsers. Some browsers also have an export limit. This allows the largest possible CSV export in each browser afaik.

Martyry answered 30/3, 2017 at 5:47 Comment(3)
target="blank" works fine for me on IE11, why wasn't that the entire answer?Leifleifer
@Martyry can you please explain me what should be the data format ?Glyn
OP mentions nothing about Angular, on which this answer is reliant.Gottwald
W
5

As of build 10547+, the Microsoft Edge browser is now supporting the download attribute on a tags.

<a href="download/image.png" download="file_name.png">Download Image</a>

Edge features update: https://dev.windows.com/en-us/microsoft-edge/platform/changelog/desktop/10547/

a[download] standard: http://www.w3.org/html/wg/drafts/html/master/links.html#attr-hyperlink-download

Wellpreserved answered 10/12, 2015 at 0:54 Comment(0)
N
3

This code fragment allows saving blob in the file in IE, Edge and other modern browsers.

var request = new XMLHttpRequest();
request.onreadystatechange = function() {

    if (request.readyState === 4 && request.status === 200) {

        // Extract filename form response using regex
        var filename = "";
        var disposition = request.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 (window.navigator.msSaveOrOpenBlob) { // for IE and Edge
            window.navigator.msSaveBlob(request.response, filename);
        } else {
            // for modern browsers
            var a = document.createElement('a');
            a.href = window.URL.createObjectURL(request.response);
            a.download = filename;
            a.style.display = 'none';
            document.body.appendChild(a);
            a.click();
        }
    }

    button.disabled = false;
    dragArea.removeAttribute('spinner-visible');
    // spinner.style.display = "none";

};
request.open("POST", "download");
request.responseType = 'blob';
request.send(formData);

For IE and Edge use: msSaveBlob

Nebuchadnezzar answered 7/4, 2017 at 8:23 Comment(0)
C
1

Use my function

It bind your atag to download file in IE

function MS_bindDownload(el) {
    if(el === undefined){
        throw Error('I need element parameter.');
    }
    if(el.href === ''){
        throw Error('The element has no href value.');
    }
    var filename = el.getAttribute('download');
    if (filename === null || filename === ''){
        var tmp = el.href.split('/');
        filename = tmp[tmp.length-1];
    }
    el.addEventListener('click', function (evt) {
        evt.preventDefault();
        var xhr = new XMLHttpRequest();
        xhr.onloadstart = function () {
            xhr.responseType = 'blob';
        };
        xhr.onload = function () {
            navigator.msSaveOrOpenBlob(xhr.response, filename);
        };
        xhr.open("GET", el.href, true);
        xhr.send();
    })
}
Circulate answered 25/5, 2019 at 1:25 Comment(0)
P
0

Append child first and then click

Or you can use window.location= 'url' ;

Praxis answered 23/8, 2013 at 4:54 Comment(1)
If I append child first and then click. It redirects to the image rather than downloadingHageman
M
0

As mentioned in earlier answer , download attribute is not supported in IE . As a work around, you can use iFrames to download the file . Here is a sample code snippet.

function downloadFile(url){
    var oIframe = window.document.createElement('iframe');
    var $body = jQuery(document.body);
    var $oIframe = jQuery(oIframe).attr({
        src: url,
        style: 'display:none'
    });
    $body.append($oIframe);

}
Macymad answered 26/3, 2015 at 12:7 Comment(3)
How is this supposed to work? I have an iframe appended right before the closing </body> tag with a source of my file.Dachia
If the content-disposoition in the header is attachment , it will try to download instead of rendering it in iFrame.Macymad
header('Content-Disposition: attachment; filename="some filename"');Macymad
S
0

I copied the code from here and updated it for ES6 and ESLint and added it to my project.

You can save the code to download.js and use it in your project like this:

import Download from './download'
Download('/somefile.png', 'somefile.png')

Note that it supports dataURLs (from canvas objects), and more... see https://github.com/rndme for details.

Semaphore answered 4/7, 2019 at 6:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.