25

I have an image encoded in base64 in a javascript variable : data:image/png;base64, base64 data

[EDIT] I need to save that file to disk without asking to the visitor to do a right click [/EDIT]

Is it possible ? How ?

Thanks in advance

Best regards

1
  • You can't. You can read this post. Commented Oct 11, 2010 at 12:28

10 Answers 10

47

I know this question is 2 years old, but hopefully people will see this update.

You can prompt the user to save an image in a base64 string (and also set the filename), without asking the user to do a right click

var download = document.createElement('a');
download.href = dataURI;
download.download = filename;
download.click();

Example:

var download = document.createElement('a');
download.href = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
download.download = 'reddot.png';
download.click();

In order to trigger a click event using Firefox, you need to do what it is explained in this SO answer. Basically:

function fireEvent(obj,evt){
  var fireOnThis = obj;
  if(document.createEvent ) {
    var evObj = document.createEvent('MouseEvents');
    evObj.initEvent( evt, true, false );
    fireOnThis.dispatchEvent( evObj );
  } else if( document.createEventObject ) {
    var evObj = document.createEventObject();
    fireOnThis.fireEvent( 'on' + evt, evObj );
  }
}
fireEvent(download, 'click')

As of 20/03/2013, the only browser that fully supports the download attribute is Chrome. Check the compatibility table here

Sign up to request clarification or add additional context in comments.

6 Comments

Worked perfectly in Chrome, but didn't do anything in IE8 running with Google Chrome Frame.
If you are using jQuery, use $(download).click(). If you are not using jQuery, check this other SO question
I think this does not work with FF, IE. It does not even react to the event, this could lead to the user wondering what's going on.
how do I save it in a directory?
Fantastic answer. very simple to use.
|
6

... without asking to the visitor anyhing ... Is it possible?

No, that would have been a security hole. If it was possible, one would be able to write malware to the enduser's disk unaskingly. Your best bet may be a (signed) Java Applet. True, it costs a bit of $$$ to get it signed (so that it doesn't pop security warnings), but it is able to write data to enduser's disk without its permission.

Comments

6

I am surprised nobody here mentioned using HTML5 blobs together with a couple of nice libraries.

You first need https://github.com/eligrey/FileSaver.js/ and https://github.com/blueimp/JavaScript-Canvas-to-Blob.

Then you can load the image into a canvas

base_image = new Image();
base_image.src ='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';

the canvas into a blob

var canvas = document.getElementById('YourCanvas');
context = canvas.getContext('2d');
// Draw image within
context.drawImage(base_image, 0,0);

and finally save it

x_canvas.toBlob(function(blob) {
saveAs(blob, "screenshot.png");
}, "image/png");

FF is not fully supported but at least you get a separate page with the image.

Check this out: http://jsfiddle.net/khhmm/9/

EDIT: this is not compatible with Safari / Mac.

3 Comments

Suppose JS is used to draw encoded data to the canvas and that the image is not cached in any way in browser-----Is it still possible to dump the canvas (perhaps "duplicate" would be a better term) and then programmatically save it in my browser's cache (or elsewhere)? Do you have a blog or some other contact point? (possible consulting offer?)
Sorry I am not sure how you can achieve this.
Thanks! This saved me a lot of heartache. I had gotten to Blob and FileSaver.js but couldn't figure out how to put them together. Great stuff.
3

As other answers already stated, you cannot do it only with javascript. If you want, you can send the data (using normal HTTP POST) to a PHP script, call header('Content-type: image/png') and output the decoded image data to the page using echo base64_decode($base64data).

This will work just as if user clicked on an image and open it or prompt him to save the file to disk (the normal browser's save file dialog).

Comments

2

It's not possible.

If it was, browsers would be massively insecure, being able to write random data to your hard disk without user interaction.

Comments

1

with javascript, you can't. the only real possibility i can think of will be a java-applet, but maybe (i don't know how long that image should be saved) you could simply add an img-tag with you png and force caching (but if the user deletes his cache, the image will be gone).

Comments

0

I think it's possible with JavaScript if you use ActiveX.

Another possibility is to make the server spit out that file with a different mime type so the browser asks the user to save it.

1 Comment

Using ActiveX restricts you however to a single webbrowser type (MSIE) and even then, MSIE in its default setup will scare the enduser with all kinds of security warnings before continuing. ActiveX, no thanks.
0

I think you can do it something(maybe not only with javascript...xul programming needed). There are Firefox addons that save images to a folder(check Firefox addons site)

1 Comment

I'm sorry, but "I think you can, go check the addons" is not an answer.
0

You can make this file as blob on the server and use setTimeout function in order to fire the download.

Comments

0

The accepted solution seems to have a limitation for large data. If you're running into this (instead of the downloaded file's name, I see "download" and "Failed - Network error" in Chrome), here's what I did in order to download a 2mb file:

const blob = await (await fetch(document.getElementById('canvasID').toDataURL())).blob();
const file = new File([blob], {type:"image/png", lastModified: new Date()});
var a = document.createElement('a');
a.href = window.URL.createObjectURL(file);
a.download = 'image.png';
a.click();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.