enlace de imagen href descargar al hacer clic

180

Genero enlaces normales como: <a href="https://stackoverflow.com/path/to/image"><img src="/path/to/image" /></a>en una aplicación web.

Cuando hago clic en el enlace, muestra la imagen en una página nueva. Si desea guardar la imagen, debe hacer clic derecho sobre ella y seleccionar "guardar como"

No quiero este comportamiento, me gustaría que aparezca un cuadro de descarga cuando haga clic en el enlace, ¿es posible solo con html o javascript? ¿Cómo?

Si no, supongo que tendría que escribir un script download.php y llamarlo al href con el nombre del archivo como parámetro ...?

Pierre
fuente
Aquí hay una manera fácil de usar esta clase de PHP: tutorialchip.com/php-download-file-script
ven el

Respuestas:

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

Todavía no es totalmente compatible con http://caniuse.com/#feat=download , pero puede usarlo con modernizr https://modernizr.com/download/?adownload-setclasses ( en Detecciones no centrales ) para verificar el soporte de el navegador.

Francisco Costa
fuente
2
Gracias por tu comentario, es bueno saberlo. Aunque necesita modernizador, ahora lo uso en todos mis proyectos, así que ... aceptaré su respuesta como la nueva respuesta
Pierre
1
Creo que puede haber entendido mal el papel de Modernizr aquí. En resumen, no agrega la funcionalidad que falta ... mira esta respuesta: stackoverflow.com/questions/18681644/…
bravokiloecho
@GauravManral, ¿qué parece ser el problema?
Francisco Costa
1
@GauravManral: IE no lo admite, como se menciona en la respuesta. Mira el enlace de caniuse proporcionado.
peirix
8
IMPORTANTE : el downloadatributo de atributo solo funciona para URL del mismo origen . MDN Docs
cespon
59

La forma más fácil de crear un enlace de descarga para una imagen o html es establecer el atributo de descarga , pero esta solución solo funciona en navegadores modernos.

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

"myimage" es un nombre de archivo para descargar. La extensión se agregará automáticamente Ejemplo aquí

Aleksey Saatchi
fuente
¿Funcionará para el cuadro de mensaje de Windows? Lo intenté, parece que no funciona, pero ¿tal vez hice algo mal?
Z77
48
<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');

}
?>
amir
fuente
17
¡Hay un problema de seguridad, debería cerrar el tipo de contenido "aplicación / descarga forzada"! que puede descargar cualquier cosa, incluida la fuente PHP del servidor.
CharlesB
3
@CharlesB tiene razón, esto le permitiría descargar cualquier cosa del servidor utilizando el recorrido del directorio: <a href="download.php?file=../dbparams.inc>">Download</a>por ejemplo. Más información aquí: en.wikipedia.org/wiki/Directory_traversal_attack
OrganicPanda
@CharlesB: entonces, ¿cuál es la forma más segura ... excepto la respuesta marcada?
HIRA THAKUR
3
Para evitar el problema de seguridad, no tome información de ruta absoluta o relativa de la solicitud; solo obtenga el nombre del archivo. Elimine la ruta, por ejemplo, usando $ file = pathInfo ($ _ GET ['file'] y luego ensamble la ruta agregando alguna ruta conocida con $ file ['basename']. Si necesita proporcionar archivos de varias carpetas, use tokens de ruta en su solicitud, que luego asigna a la ruta real en su función de descarga.
Alexander233
1
O cree una tabla con la relación Id, Token, Ruta, obtenga el token de la URL, verifique la Ruta en la base de datos y devuelva ese archivo. Eso sería más seguro. Pero obviamente más complicado.
Felype
10

No lo es. Necesitará algo en el servidor para enviar un encabezado Content-Disposition para configurar el archivo como un archivo adjunto en lugar de estar en línea. Sin embargo, podría hacer esto con una configuración simple de Apache.

He encontrado un ejemplo de cómo hacerlo usando mod_rewrite , aunque sé que hay una manera más simple.

Quentin
fuente
66
Oye, dices: "aunque sé que hay una manera más simple" ... ¿cuál? ^ _ ^
Pierre
Si pudiera encontrar los detalles, los publicaría. No puedo encontrarlos en este momento y no tengo tiempo para dedicarme a una búsqueda exhaustiva.
Quentin
1
Está bien, gracias por tu ayuda. Acabo de crear una página php que genera la descarga ...
Pierre
7

Prueba esto...

<a href="/path/to/image" download>
    <img src="/path/to/image" />
 </a>
edCoder
fuente
5

Atributo de descarga HTML para especificar que el destino se descargará cuando un usuario haga clic en el hipervínculo.

Este atributo solo se usa si el atributo href está configurado.

El valor del atributo será el nombre del archivo descargado. No hay restricciones en los valores permitidos, y el navegador detectará automáticamente la extensión de archivo correcta y la agregará al archivo (.img, .pdf, .txt, .html, etc.).

Código de ejemplo:

<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>

Salida :

Descargar imagen >>

Descarga HTML o Chrome

Descargar imagen >>

Rizo
fuente
1
Hola, gracias por la respuesta. Algunas personas ya propusieron esto, pero creo que todavía no es totalmente compatible. Por otro lado, su enlace de descarga no funciona para mí en Chrome más reciente
Pierre
Hola Pierre, prueba esto <a href=" w3schools.com/images/myw3schoolsimage.jpg "download> Descargar imagen >> </a> gracias
Rizo
4

No puede hacerlo con html / javascript puro. Esto se debe a que tiene una conexión separada con el servidor web para recuperar un archivo separado (la imagen) y un servidor web normal servirá el archivo con encabezados de contenido configurados para que el navegador que lee el tipo de contenido decida que el tipo puede manejarse internamente.

La forma de forzar al navegador a que no maneje el archivo internamente es cambiar los encabezados (disposición de contenido preferiblemente o tipo de contenido) para que el navegador no intente manejar el archivo internamente. Puede hacerlo escribiendo un script en el servidor web que establezca dinámicamente los encabezados (es decir, download.php) o configurando el servidor web para que devuelva diferentes encabezados para el archivo que desea descargar. Puede hacer esto por directorio en el servidor web, lo que le permitiría escapar sin escribir ningún php o javascript, simplemente tenga todas sus imágenes de descarga en esa ubicación.

Colin Pickard
fuente
1
No. Mentir sobre el tipo de contenido no es la única forma de lograrlo. Consulte el encabezado de respuesta HTTP de disposición de contenido.
Quentin
4

Código simple para descargar imágenes con una imagen haciendo clic usando 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>
Sashtha Manik
fuente
2

Descarga de imágenes con el uso de hacer clic en la imagen!

¡Hice este código simple! :)

<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>
Sashtha Manik
fuente