1

I am looking for a way to force the browser to download an image instead of just display it.

I already looked a lot (and deeply) and there seems to be no standard way to do it properly.

The way Facebook do it, it's with some PHP I guess they put a parameter at the end : ?dl=1

So it's certainly a PHP page behind with an url rewritting i guess

<a class="itemAnchor" role="menuitem" tabindex="-1"  href="http://a5.sphotos.ak.fbcdn.net/hphotos-ak-ash4/327910_2733459209258_1040639162_2895571_6924037615_o.jpg?dl=1" rel="ignore"><span class="itemLabel fsm">Download</span></a>

So if you have any clue how they do it... My clue is that they probably do something in the headers of the PHP page

Jerome Ansia
  • 6,854
  • 11
  • 53
  • 99
  • 1
    You might want to give this article a read: http://www.ryboe.com/tutorials/php-headers-force-download Seems to be exactly what you're after, as long as you're actually serving the image yourself. – MichD Mar 28 '12 at 22:35

3 Answers3

6

They simply force downloading using HTTP headers just like you do with any other file:

<?php
    $file = 'C:\\test.jpg';

    header('Cache-Control: public');
    header('Content-Description: File Transfer');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Type: '.mime_content_type($file));
    header('Content-Transfer-Encoding: binary');
    header('Content-Length: '.filesize($file));

    readfile($file);
?>

X-SendFile

For larger files or busy webservers, I would suggest the use of X-SendFile header instead of using readfile() function (note that you need mod_xsendfile installed in Apache).

    header('X-Sendfile: '.$file);
    //readfile($file);

.htccess

As you noticed, the Facebook URL points at a jpg file, rather than a PHP one. You will need to have URL rewriting in a .htaccess file to do this trick.

Something like the following should work (note you will need to use the real URL, checking the contents of $_SERVER to do so).

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]
</IfModule>
Christian
  • 27,509
  • 17
  • 111
  • 155
2

You'll have to define the Content-Disposition variable in your header:

<?php
   header("Content-Disposition: attachment; filename='downloaded.png'");
?>
Jon McIntosh
  • 1,263
  • 8
  • 14
1

You can achieve this by setting the appropriate headers before sending the file. Specifically you can set the Content-Type to whatever your content type is and Content-Disposition: attachment; filename=<yourfilename>.

There are some gotchas with IE; check this answer for more info.

Community
  • 1
  • 1
cosmix
  • 185
  • 6