Téléchargement du lien de l'image href en cliquant

180

Je génère des liens normaux comme: <a href="https://stackoverflow.com/path/to/image"><img src="/path/to/image" /></a>dans une application Web.

Lorsque je clique sur le lien, il affiche l'image dans une nouvelle page. Si vous souhaitez enregistrer l'image, vous devez faire un clic droit dessus et sélectionner «enregistrer sous»

Je ne veux pas de ce comportement, j'aimerais qu'une boîte de téléchargement apparaisse lorsque je clique sur le lien, est-ce possible uniquement avec html ou javascript? Comment?

Sinon, je suppose que je devrais écrire un script download.php et l'appeler dans le href avec le nom du fichier comme paramètre ...?

Pierre
la source
Voici un moyen simple d'utiliser cette classe PHP: tutorialchip.com/php-download-file-script
ven

Réponses:

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

Ce n'est pas encore entièrement pris en charge http://caniuse.com/#feat=download , mais vous pouvez l'utiliser avec modernizr https://modernizr.com/download/?adownload-setclasses ( sous Détectes non-core ) pour vérifier la prise en charge de le navigateur.

Francisco Costa
la source
2
Merci pour votre commentaire, c'est une bonne chose à savoir. Bien que vous ayez besoin de moderniser, je l'utilise maintenant dans tous mes projets donc ... J'accepterai votre réponse comme nouvelle réponse
Pierre
1
Je pense que vous avez peut-être mal compris le rôle de Modernizr ici. En bref, cela n'ajoute pas la fonctionnalité qui manque ... voir cette réponse: stackoverflow.com/questions/18681644/…
bravokiloecho
@GauravManral quelles coutures pour être le problème?
Francisco Costa
1
@GauravManral: IE ne le prend pas en charge, comme mentionné dans la réponse. Regardez le lien caniuse fourni.
peirix
8
IMPORTANT : l' downloadattribut attributte ne fonctionne que pour les URL de même origine . MDN Docs
cespon
59

Le moyen le plus simple de créer un lien de téléchargement pour une image ou un html consiste à définir l' attribut de téléchargement , mais cette solution ne fonctionne que dans les navigateurs modernes.

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

"myimage" est un nom de fichier à télécharger. L'extension sera ajoutée automatiquement Exemple ici

Aleksey Saatchi
la source
Cela fonctionnera-t-il pour Windows Message Box? J'ai essayé, cela ne semble pas fonctionner, mais peut-être que j'ai fait quelque chose de 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
la source
17
Il y a un problème de sécurité, devrait fermer "application / téléchargement forcé" Content-Type! qui peut télécharger n'importe quoi, y compris la source PHP du serveur!
CharlesB
3
@CharlesB a raison, cela vous permettrait de télécharger n'importe quoi depuis le serveur en utilisant la traversée de répertoire: <a href="download.php?file=../dbparams.inc>">Download</a>par exemple. Plus d'infos ici: en.wikipedia.org/wiki/Directory_traversal_attack
OrganicPanda
@CharlesB: alors quel est le moyen le plus sûr ... sauf la réponse cochée ??
HIRA THAKUR
3
Pour contourner le problème de sécurité, ne prenez pas d'informations de chemin absolues ou relatives de la demande; obtenir uniquement le nom du fichier. Supprimez le chemin, par exemple en utilisant $ file = pathInfo ($ _ GET ['file'] puis assemblez le chemin en ajoutant un chemin connu avec $ file ['basename']. Si vous avez besoin de fournir des fichiers à partir de divers dossiers, utilisez des jetons de chemin dans votre demande, que vous mappez ensuite au chemin réel dans votre fonction de téléchargement.
Alexander233
1
Ou créez une table avec une relation Id, Token, Path, obtenez le jeton à partir de l'URL, vérifiez le chemin dans la base de données et renvoyez ce fichier. Ce serait plus sûr. Mais évidemment plus compliqué.
Felype
10

Non, ça ne l'est pas. Vous aurez besoin de quelque chose sur le serveur pour envoyer un en-tête Content-Disposition pour définir le fichier en tant que pièce jointe au lieu d'être en ligne. Vous pouvez le faire avec une configuration Apache simple.

J'ai trouvé un exemple de le faire en utilisant mod_rewrite , bien que je sache qu'il existe un moyen plus simple.

Quentin
la source
6
Hé, vous dites: "bien que je sache qu'il existe un moyen plus simple" ... lequel? ^ _ ^
Pierre
Si je pouvais trouver les détails, je les posterais. Je ne peux pas les trouver pour le moment et je n'ai pas le temps de me consacrer à une recherche approfondie.
Quentin
1
C'est bien merci pour votre aide. Je viens de créer une page php qui génère le téléchargement ...
Pierre
7

Essaye ça...

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

Attribut de téléchargement HTML pour spécifier que la cible sera téléchargée lorsqu'un utilisateur clique sur le lien hypertexte.

Cet attribut n'est utilisé que si l'attribut href est défini.

La valeur de l'attribut sera le nom du fichier téléchargé. Il n'y a aucune restriction sur les valeurs autorisées et le navigateur détectera automatiquement l'extension de fichier correcte et l'ajoutera au fichier (.img, .pdf, .txt, .html, etc.).

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

Production :

Télécharger l'image >>

Téléchargement html5 ou chrome

Télécharger l'image >>

Rizo
la source
1
Hé, merci pour la réponse. Certaines personnes ont déjà proposé cela, mais je pense que ce n'est toujours pas entièrement pris en charge. Par contre, votre lien de téléchargement ne fonctionne pas pour moi sur la dernière version de Chrome
Pierre
Hey Pierre, essayez ce <a href=" w3schools.com/images/myw3schoolsimage.jpg "télécharger> Télécharger l'image >> </a> merci
Rizo
4

Vous ne pouvez pas le faire avec du html / javascript pur. En effet, vous disposez d'une connexion distincte au serveur Web pour récupérer un fichier séparé (l'image) et un serveur Web normal servira le fichier avec des en-têtes de contenu définis afin que le navigateur lisant le type de contenu décide que le type peut être géré en interne.

La façon de forcer le navigateur à ne pas gérer le fichier en interne consiste à modifier les en-têtes (de préférence la disposition du contenu ou le type de contenu) afin que le navigateur n'essaie pas de gérer le fichier en interne. Vous pouvez le faire soit en écrivant un script sur le serveur Web qui définit dynamiquement les en-têtes (par exemple download.php), soit en configurant le serveur Web pour renvoyer différents en-têtes pour le fichier que vous souhaitez télécharger. Vous pouvez le faire sur une base par répertoire sur le serveur Web, ce qui vous permettrait de vous en sortir sans écrire de php ou de javascript - ayez simplement toutes vos images téléchargées à cet endroit.

Colin Pickard
la source
1
Non. Mentir sur le type de contenu n'est pas le seul moyen d'y parvenir. Voir l'en-tête de réponse HTTP de disposition du contenu.
Quentin
4

Code simple pour le téléchargement d'image avec une image en cliquant en utilisant 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>
Manik Sashtha
la source
2

Téléchargement d'image avec l'utilisation de l'image en cliquant!

J'ai fait ce code 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>
Manik Sashtha
la source