0

I'm looking for a cross-browser solution to display a "Save As" dialog in Javascript. I had been using this method in a previous project, but it's broken in IE 11 (because the window.ActiveXObject has changed and IE 11 now slips into the first conditional below):

function saveFile(fileURL, fileName) {
    if (!window.ActiveXObject) {
        // Non-IE
        var save = document.createElement('a');
        save.href = fileURL;
        save.target = '_blank';
        save.download = fileName || fileURL;
        var evt = document.createEvent('MouseEvents');
        evt.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0,
            false, false, false, false, 0, null);
        save.dispatchEvent(evt);
        (window.URL || window.webkitURL).revokeObjectURL(save.href);
    } else if (document.execCommand) {
        // IE
        var _window = window.open(fileURL, "_blank");
        _window.document.close();
        _window.document.execCommand('SaveAs', true, fileName || fileURL)
        _window.close();
    }
}

My understanding is that the IE team did this intentionally to prevent using this method for browser detection. Can I use some other kind of feature/object detection to make it work again. Or can I (preferably) remove the conditionals and just have one piece of code for all browsers. When the first conditional runs in IE, the error I see is:

DOM7001: Invalid argument 'url'. Failed to revoke Blob URL: '[the url...]'.
File: localhost:8080

I know that browser detection is an option (like WhichBrowser, for example) but even the author of that warns that feature/object detection really is the way to go.

RTF
  • 6,214
  • 12
  • 64
  • 132
  • What browser doesn't support the "Save as" dialog if you do it correctly and pass the right headers ? – adeneo Apr 19 '14 at 14:31
  • When I used the Content-Disposition header in HTTP response, none of the browsers would trigger a save-as dialog, this was the only way I could get it to work. Are you saying that all browsers respect the Content-Disposition header with "attachment;filename=" value. Do you think it's a problem on my end? – RTF Apr 19 '14 at 14:33
  • Normally the headers should trigger a download dialog. – adeneo Apr 19 '14 at 15:00
  • I know, but it just wouldn't work for me. It was an ajax request though, might that be the problem. I mean, in order for that to work, does the user have to actually click on a form button or something. If it's an ajax request, will the browser trigger the save-as dialog when the ajax callback is triggered? (provided the content-disposition header is correctly set) – RTF Apr 19 '14 at 15:07
  • It does not work at all with ajax requests, as the headers aren't loaded. It makes no sense to do an ajax request to a file that should trigger a download dialog. – adeneo Apr 19 '14 at 15:09
  • What if the user makes a request that takes a little while to complete, and ultimately results in a file being returned that should present a save-as dialog. This is my use-case. If not an AJAX request, then what? – RTF Apr 19 '14 at 15:14
  • Found this: http://stackoverflow.com/questions/16086162/handle-file-download-from-ajax-post – RTF Apr 19 '14 at 15:34
  • @adeneo I think it makes sense to download the desired file with AJAX and use data URIs like [this answer](http://stackoverflow.com/a/833107/1529630) to produce the save-as dialog. – Oriol Apr 19 '14 at 15:35

3 Answers3

1

I think it's probably a better solution to just embed a hidden iFrame in the HTML body and have the JS set the src of the iFrame to the URL. Once the src is set, that'll immediately trigger the Save-As dialog if the src URL wants it to e.g.

<body>
...
...
<iframe style="display:none" id="hidden-iframe"></iframe>
</body>

and...

document.getElementById("hidden-iframe").src = myURL;

Seems to be working in all the browsers I've checked so far, including IE (gasp!).

RTF
  • 6,214
  • 12
  • 64
  • 132
0

Just My 2 cents, but your problem as posted is really how to test for link download support. Since you're not actually using ActiveX, you shouldn't use it to detect the feature. It's not far off from testing against the user agent.

Instead verify that the anchor's download attribute is not of type string (which it will not be in trident browsers). Then execute your IE "save as" code.

The problem I'm having at present is just evoking document.execCommand('SaveAs') is crashing IE 11 100% of the time.

Paul Fox
  • 161
  • 2
  • 1
0

Might want to try using msSaveBlob if something like this is what you are looking for in IE.

Pokechu22
  • 4,984
  • 9
  • 37
  • 62