Force Browser to download Image with Javascript window.open?

Is there a way to make an image a download once you click on it (without right-click save image as)?

I'm using a small Javascript function to call the download page:

<a href="#" 
   onclick="window.open('download.php?file=test.jpg', 'download', 'status=0');"
>Click to download</a>

In the download.php page I have something like:

$file = $_GET['file'];
header('Content-Description: File Transfer');
header("Content-type: image/jpg");
header("Content-disposition: attachment; filename= ".$file."");
readfile($file);

But it doesn't work. What am I doing wrong?
Thanks in advance!


Solution 1:

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

Solution 2:

I think you forgot to add Path on the header

if(isset($_GET['file'])){
    //Please give the Path like this
    $file = 'images/'.$_GET['file'];

    if (file_exists($file)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        ob_clean();
        flush();
        readfile($file);
        exit;
    }
}

Solution 3:

Or you can use .htaccess file for all your image files. In case you want to force the browser to download all your images (f.e. from a table list):

RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^download$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .(jpe?g|gif|png)$ index.php?file=noFoundFilePage [L,NC]
RewriteCond %{QUERY_STRING} ^download$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .(jpe?g|gif|png)$ - [L,NC,T=application/octet-stream] 

This looks for image files a tries to force download them into the browser. The -f RewriteConds also checks that the file exsist.. The last rule ensures that download is used only for certain file types.

Solution 4:

This worked for me

header("Pragma: public");
header('Content-disposition: attachment; filename='.$title);
header("Content-type: ".mime_content_type($sample_file));
header('Content-Transfer-Encoding: binary');
ob_clean(); 
flush(); 
readfile($sample_file);

I also added the following to .htaccess

SetEnvIf Request_URI "\.jpg$" requested_jpg=jpg
Header add Content-Disposition "attachment" env=requested_jpg

Not sure if that helps?

Solution 5:

If you're on an apache server this is really simple.

  1. Create a file called .htaccess in the directory in which your files exist. For me it was assets/.htaccess.
  2. Add the following to the file AddType application/octet-stream .jpg. You can add a new line for each file extension that you need. E.g. AddType application/octet-stream .pdf
  3. Save your file
  4. Clear your browser cache
  5. Refresh your browser and enjoy!