211

I generate normal links like: <a href="/path/to/image"><img src="/path/to/image" /></a> in a web app.

When I click on the link, it displays the picture in a new page. If you want to save the picture, then you need to right click on it and select "save as"

I don't want this behaviour, I would like to have a download box popping out when I click on the link, is that possible just with html or javascript? How?

If not I guess I would have to write a download.php script and call it into the href with the file name as parameter...?

bstpierre
  • 30,042
  • 15
  • 70
  • 103
Pierre
  • 4,976
  • 12
  • 54
  • 76
  • Here is an easy way of doing using this PHP class: http://www.tutorialchip.com/php-download-file-script/ – ven Nov 23 '11 at 19:24

10 Answers10

293
<a download="custom-filename.jpg" href="/path/to/image" title="ImageName">
    <img alt="ImageName" src="/path/to/image">
</a>

It's not yet fully supported caniuse, but you can use with modernizr (under Non-core detects) to check the support of the browser.

Francisco Costa
  • 6,713
  • 5
  • 34
  • 43
  • 3
    Thanks for your comment, it's a good thing to know. Although you need modernizr, I now use it in all my projects so... I'll accept your answer as the new answer – Pierre May 01 '13 at 12:05
  • 2
    I think you might have misunderstood the role of Modernizr here. In short, it doesn't add functionality that's missing... see this answer: http://stackoverflow.com/questions/18681644/modernizr-a-download-for-download-attribute-does-not-work-in-ie-safari-and-and – bravokiloecho Jul 06 '14 at 11:20
  • @GauravManral what seams to be the problem? – Francisco Costa Mar 25 '15 at 15:47
  • i just wanted to download a image on click of a link rather to open it in new link, – Gaurav Manral Mar 30 '15 at 07:24
  • 1
    @GauravManral: IE doesn't support it, as mentioned in the answer. Look at the caniuse link provided. – peirix Jul 06 '15 at 10:25
  • I tested this code on Chrome and Firefox, it still just downloads the file as the actual href name. The 'download="filename.jpg"' does not seem to work on either browser. I don't see the point of this. – Michael d May 11 '17 at 07:30
  • 45
    **IMPORTANT**: `download` attributte attribute only works for **same-origin URLs**. [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Attributes) – cespon Mar 20 '19 at 10:47
  • only download attribute is enough. – Ali Rasouli Oct 08 '19 at 09:54
  • 2
    What about different origins? It's only opening the images but not downloading. Any solution? – Minhaz Jul 07 '22 at 04:56
67

The easiest way of creating download link for image or html is setting download attribute, but this solution works in modern browsers only.

<a href="/path/to/image" download="myimage"><img src="/path/to/image" /></a>

"myimage" is a name of file to download. Extension will be added automatically Example here

Aleksey Saatchi
  • 769
  • 5
  • 6
  • Will this work for Windows Message Box? I tried, it seems not working, but maybe I did something wrong?! – Z77 Feb 13 '14 at 13:04
47
<a href="download.php?file=path/<?=$row['file_name']?>">Download</a>

download.php:

<?php

$file = $_GET['file'];

download_file($file);

function download_file( $fullPath ){

  // Must be fresh start
  if( headers_sent() )
    die('Headers Sent');

  // Required for some browsers
  if(ini_get('zlib.output_compression'))
    ini_set('zlib.output_compression', 'Off');

  // File Exists?
  if( file_exists($fullPath) ){

    // Parse Info / Get Extension
    $fsize = filesize($fullPath);
    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);

    // Determine Content Type
    switch ($ext) {
      case "pdf": $ctype="application/pdf"; break;
      case "exe": $ctype="application/octet-stream"; break;
      case "zip": $ctype="application/zip"; break;
      case "doc": $ctype="application/msword"; break;
      case "xls": $ctype="application/vnd.ms-excel"; break;
      case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
      case "gif": $ctype="image/gif"; break;
      case "png": $ctype="image/png"; break;
      case "jpeg":
      case "jpg": $ctype="image/jpg"; break;
      default: $ctype="application/force-download";
    }

    header("Pragma: public"); // required
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false); // required for certain browsers
    header("Content-Type: $ctype");
    header("Content-Disposition: attachment; filename=\"".basename($fullPath)."\";" );
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".$fsize);
    ob_clean();
    flush();
    readfile( $fullPath );

  } else
    die('File Not Found');

}
?>
Jason Plank
  • 2,336
  • 5
  • 31
  • 40
amir
  • 479
  • 4
  • 2
  • 17
    There is a security problem, should closed "application/force-download" Content-Type! which can download anything including server PHP source! – CharlesB May 22 '12 at 06:28
  • 3
    @CharlesB is right, this would allow you to download anything from the server using directory traversal: `Download` for example. More info here: http://en.wikipedia.org/wiki/Directory_traversal_attack – OrganicPanda Aug 10 '12 at 09:46
  • @CharlesB:then whats the safest way...except the ticked answer?? – HIRA THAKUR Aug 14 '13 at 14:25
  • Anyone feel like suggesting changes to the above code in order to get rid of the security problem? Perhaps set the default $ctype to null? – InanisAtheos Jan 07 '14 at 12:33
  • 3
    To get around the security problem, don't take absolute or relative path information from the request; only get the file name. Strip the path, e.g using $file = pathInfo($_GET['file'] and then assemble the path by appending some known path with $file['basename']. If you need to provide files from various folders, use path tokens in your request, which you then map to the actual path in your download function. – Alexander233 Jan 22 '14 at 17:04
  • Is this thing can work ? if ($ext == "php"){ die('Not Allowed'); exit;} – WhiteHorse Oct 24 '14 at 06:35
  • The only issue with a PHP solution like this is you can't force a download and still print the rest of the page. – eozzy Feb 03 '15 at 09:09
  • 1
    Or create a table with Id, Token, Path relationship, get the token from URL, check the Path in the database and return that file. That would be safer. But obviously more complicated. – Felype Jun 29 '15 at 18:13
  • after download, i want to return to some other page. Then, what will be the mechanism then.? – Nana Partykar Aug 18 '15 at 09:21
13

If you are Using HTML5 you can add the attribute 'download' to your links.

<a href="/test.pdf" download>

http://www.w3schools.com/tags/att_a_download.asp

Jijo Paulose
  • 1,896
  • 18
  • 20
11

No, it isn't. You will need something on the server to send a Content-Disposition header to set the file as an attachment instead of being inline. You could do this with plain Apache configuration though.

I've found an example of doing it using mod_rewrite, although I know there is a simpler way.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 6
    Hey, you say: "although I know there is a simpler way"... which one? ^_^ – Pierre Mar 09 '10 at 10:30
  • If I could find the details, I'd post them. I can't find them right now and don't have the time to devote to an extensive search. – Quentin Mar 09 '10 at 10:31
  • 1
    It's fine thanks for your help. I just created a php page that generates the download... – Pierre Mar 09 '10 at 11:53
8

Try this...

<a href="/path/to/image" download>
    <img src="/path/to/image" />
 </a>
Edwin Thomas
  • 1,186
  • 2
  • 18
  • 31
5

HTML download attribute to specify that the target will be downloaded when a user clicks on the hyperlink.

This attribute is only used if the href attribute is set.

The value of the attribute will be the name of the downloaded file. There are no restrictions on allowed values, and the browser will automatically detect the correct file extension and add it to the file (.img, .pdf, .txt, .html, etc.).

Example code:

<a href="https://www.w3schools.com/images/myw3schoolsimage.jpg"> Download Image >></a>

HTML5:

<a href="https://www.w3schools.com/images/myw3schoolsimage.jpg" download> Download Image >></a>

Output:

Download Image >>

Html5 download or chrome

Download Image >>

Vladimir Salguero
  • 5,609
  • 3
  • 42
  • 47
Rizwan
  • 3,741
  • 2
  • 25
  • 22
4

You can't do it with pure html/javascript. This is because you have a seperate connection to the webserver to retrieve a separate file (the image) and a normal webserver will serve the file with content headers set so that the browser reading the content type will decide that the type can be handled internally.

The way to force the browser not to handle the file internally is to change the headers (content-disposition prefereably, or content-type) so the browser will not try to handle the file internally. You can either do this by writing a script on the webserver that dynamically sets the headers (i.e. download.php) or by configuring the webserver to return different headers for the file you want to download. You can do this on a per-directory basis on the webserver, which would allow you to get away without writing any php or javascript - simply have all your download images in that one location.

Grhm
  • 6,726
  • 4
  • 40
  • 64
Colin Pickard
  • 45,724
  • 13
  • 98
  • 148
  • 1
    No. Lying about the content-type is not the only way to achieve this. See the content-disposition HTTP response header. – Quentin Mar 09 '10 at 10:29
3

Simple Code for image download with an image clicking using php

<html>
<head>
    <title> Download-Button </title>
</head>
<body>
    <p> Click the image ! You can download! </p>
    <?php
    $image =  basename("http://localhost/sc/img/logo.png"); // you can here put the image path dynamically 
    //echo $image;
    ?>
    <a download="<?php echo $image; ?>" href="http://localhost/sc/img/logo.png" title="Logo title">
        <img alt="logo" src="http://localhost/sc/img/logo.png">
    </a>
</body>
Community
  • 1
  • 1
2

Image download with using image clicking!

I did this simple code!:)

<html>
<head>
<title> Download-Button </title>
</head>
<body>
<p> Click the image ! You can download! </p>
<a download="logo.png" href="http://localhost/folder/img/logo.png" title="Logo title">
<img alt="logo" src="http://localhost/folder/img/logo.png">
</a>
</body>
</html>
Community
  • 1
  • 1