13

I have a data uri in memory that I would like the user to download.

This fiddle works in chrome but not FF: http://jsfiddle.net/6W2TY/

When you click run it will download the tiny image in chrome and do nothing in FF. Can anyone help me understand why it doesn't work in FF and what I need to do to make it work?

Thanks!

asutherland
  • 2,849
  • 4
  • 32
  • 50

2 Answers2

36

I realize this is an old post, but I came across it when I had a similar problem downloading files in FF. This may not have worked in FF at the time the question was written, but it does now.

a = document.createElement('a');
document.body.appendChild(a);
a.download = name;
a.href = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABWSURBVDhPY0xISPh//0UOA7mAiVyNMH2jBjAwkBQGjD9KGBTEJ6OEO0kG2NvbMwCjnXwDsEU5SS5ANuDhjRCGJbPFSQsDdBfIyMhQZgDIQLK9QLWkDABPsQw5I+5qmAAAAABJRU5ErkJggg==";
a.click();

Changes from the original fiddle:

  1. Add call to document.body.appendChild(a);
  2. Change triggerEvent() to a.click()

Here is an updated fiddle: http://jsfiddle.net/70f91ao7/6/

John Myczek
  • 12,076
  • 4
  • 31
  • 44
12

You are using the new (html5) download attribute. As far as I know this is only supported in Chrome and not (yet) in Firefox.

Update 3-2018
This feature is now supported in almost all major browsers (No IE support).

Alternative: Using location.href

Another way to force a download is to redirect the user to the image like this:

// generate the image
var img = ""

// then call a function maybe onClick or something
downloadImage(img);

function downloadImage(data) {
    location.href = "data:application/octet-stream;base64," + data;
}

Or the short version

location.href = "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABWSURBVDhPY0xISPh//0UOA7mAiVyNMH2jBjAwkBQGjD9KGBTEJ6OEO0kG2NvbMwCjnXwDsEU5SS5ANuDhjRCGJbPFSQsDdBfIyMhQZgDIQLK9QLWkDABPsQw5I+5qmAAAAABJRU5ErkJggg=="

Alternative: Server Side

As an alternative, if you are processing the image serverside you can force a download by setting the content-disposition header.

PHP Example

header('Content-Disposition: attachment; filename="image.png"');
Bart
  • 636
  • 6
  • 16
  • I'm building the image I want the user to be able to download client side. Is there any way to let a user download a client side image that I have the data-uri for in FF? It looks like the download attribute has been in chrome for over a year so I'm not sure FF has any plans to support it ever. – asutherland Oct 01 '12 at 16:21
  • I added my answer to include an javascript only alternative. Is this something you can use? – Bart Oct 01 '12 at 17:12
  • Unfortunately location.href option means the file doesn't have the right mime type and I cannot set the default file name to anything reasonable, is there a way around that? Marking this as answer regardless as it was quite helpful. Thanks. – asutherland Oct 01 '12 at 22:19
  • I don't know if you read this, but the only solution (workaround / hack) I can think of to set the mime type and filename is to post the image back to the server and return it again with the right headers. – Bart Oct 02 '12 at 20:30
  • Beware: this approach may trigger 'beforeunload' event – Eduard Kolosovskyi Mar 01 '19 at 12:29