Force Browser to Download Image with JavaScript Window.Open

Force Browser to download Image with Javascript window.open?

Use application/octet-stream instead of image/jpg:

If [the Content-Disposition] header is used in a response with the application/octet-stream content-type, the implied suggestion is that the user agent should not display the response, but directly enter a `save response as...' dialog.

— RFC 2616 – 19.5.1 Content-Disposition

Easiest way to open a download window without navigating away from the page

7 years have passed and
I don't know whether it works for IE6 or not, but this prompts OpenFileDialog in FF and Chrome.

var file_path = 'host/path/file.ext';
var a = document.createElement('A');
a.href = file_path;
a.download = file_path.substr(file_path.lastIndexOf('/') + 1);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);

How to download a file using window.open()

To force the browser to download the file (instead of displaying it, in another tab or the current one) requires a special header to be sent along with the file body.

That's only possible if you can modify some things server-side.

You should send following headers :

  • Content-Disposition: attachment; filename"myfile.txt"
  • Content-Type: application/octet-stream; name="myfile.txt"
  • Content-Transfer-Encoding: binary

Of course, replace application/octet-stream by the content-type of your file, if known (application/pdf, image/jpeg, etc.)

Force Download an Image Using Javascript

You need to use server-side scripting for this. Search on stackoverflow.

Alternately, your server might allow you to alter headers dynamically via configuration.

Apache solution with mod_headers

Place your downloadable images in a directory. Inside this directory, create a .htaccess file with the following contents:

SetEnvIf Request_URI "([^/]+\.jpg)$" REQUESTED_IMAGE_BASENAME=$1
SetEnvIf Request_URI "([^/]+\.png)$" REQUESTED_IMAGE_BASENAME=$1
Header set Content-Disposition "attachment; filename=\"%{REQUESTED_IMAGE_BASENAME}e\"" env=REQUESTED_IMAGE_BASENAME

Test Request:

HEAD /test/Water%20lilies.jpg HTTP/1.1
Host: localhost

Test Response:

HTTP/1.1 200 OK
Date: Sat, 23 Jul 2011 09:03:52 GMT
Server: Apache/2.2.17 (Win32)
Last-Modified: Thu, 23 Aug 2001 14:00:00 GMT
ETag: "26000000017df3-14752-38c32e813d800"
Accept-Ranges: bytes
Content-Length: 83794
Content-Disposition: attachment; filename="Water lilies.jpg"
Content-Type: image/jpeg

HTML5 Solution

You can use the HTML5 download attribute on anchors:

<p>Example 1<br>

<a href="http://dummyimage.com/600x400/000/fff.png" download>Download this image</a></p>

<p>Example 2<br>

<a href="http://dummyimage.com/600x400/000/fff.png" download="alternate-filename.png"><img

src="http://dummyimage.com/150x100/000/fff.png"></a></p>

How to force a download instead of opening the file?

  1. Use canvas.toDataURL to get the canvas content as an image src
  2. open a window/popup
  3. add an <img> to the popup
  4. assign the image src as src for the image

function saveForm() {
html2canvas(document.body, {
onrendered: function(canvas) {
var img = canvas.toDataURL("image/png");
var open = window.open('','','width=500,height=500')
open.document.write('<img id="img" style="width="400">');
open.document.getElementById('img').setAttribute('src', img);
}
});
}

Tested the code inside onrendered, and it works for sure - but not along with html2canvas.

If you right click on the image in the popup -> save image as, the saved image is valid.

The reason why I am using setAttribute and not simply src="..." is that if you assign the data src as string the image get corrupted.


Edit
I know :( I think you have to set HTTP Headers to force a download, and this can only be done by the server (correct me if I am wrong). I think of a "proxy" on the server like this mockup, download.php :

<?
$src=$_POST['src'];
header('Content-Type: image/png');
header('Content-Disposition: inline; filename="download.png"');
header('Content-Length: '.count($src));
echo $src;
?>

and call it by

var img = canvas.toDataURL("image/png");
window.open('download.php?src='+img);

But then you will face a lot of Request-URI Too Large-messages, unless all your canvas-images is in icon-size.

A second way - and probably the one that would work - would be to save img in a table on the server through ajax, eg calling a script with img src that saves it. When this call is finished, you could call another server script with the correct headers for image download, including the img src saved just before. But this is a more extensive approach you could try yourself..?



Related Topics



Leave a reply



Submit