200 votes

href image lien télécharger sur clic

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

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

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

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

0 votes

Voici un moyen simple de le faire en utilisant cette classe PHP : tutorialchip.com/php-download-file-script

275voto

Francisco Costa Points 875
<a download="custom-filename.jpg" href="http://stackoverflow.com/path/to/image" title="ImageName">
    <img alt="ImageName" src="/path/to/image">
</a>

Il n'est pas encore totalement pris en charge caniuse mais vous pouvez l'utiliser avec modernizr ( sous la rubrique détecteurs non essentiels ) pour vérifier le support du navigateur.

2 votes

Merci pour votre commentaire, c'est une bonne chose à savoir. Bien que vous ayez besoin de modernizr, je l'utilise maintenant dans tous mes projets donc... Je vais accepter votre réponse comme la nouvelle réponse

1 votes

Je pense que vous avez mal compris le rôle de Modernizr ici. En bref, il n'ajoute pas de fonctionnalité manquante... voir cette réponse : stackoverflow.com/questions/18681644/

0 votes

@GauravManral Quel semble être le problème ?

64voto

Aleksey Saatchi Points 401

Le moyen le plus simple de créer un lien de téléchargement pour une image ou un fichier html est de définir les paramètres suivants attribut de téléchargement mais cette solution ne fonctionne que dans les navigateurs modernes.

<a href="http://stackoverflow.com/path/to/image" download="myimage"><img src="/path/to/image" /></a>

"monimage" est le nom du fichier à télécharger. L'extension sera ajoutée automatiquement Exemple ici

0 votes

Cela fonctionnera-t-il pour la boîte à messages de Windows ? J'ai essayé, il semble que cela ne fonctionne pas, mais peut-être que j'ai fait quelque chose de mal !

48voto

amir Points 231
<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');

}
?>

17 votes

Il y a un problème de sécurité, devrait fermer "application/force-download" Content-Type ! qui peut télécharger n'importe quoi, y compris la source PHP du serveur !

3 votes

@CharlesB a raison, cela vous permettrait de télécharger n'importe quoi à partir du serveur en utilisant la traversée de répertoire : <a href="download.php?file=../dbparams.inc>">Download</a> par exemple. Plus d'informations ici : fr.wikipedia.org/wiki/Directory_traversal_attack

0 votes

@CharlesB:alors quel est le moyen le plus sûr...à l'exception de la réponse cochée... ?

11voto

Quentin Points 325526

Non, ce n'est pas le cas. Vous aurez besoin de quelque chose sur le serveur pour envoyer un en-tête Content-Disposition afin de définir le fichier comme une pièce jointe au lieu d'être en ligne. Vous pouvez cependant faire cela avec une simple configuration d'Apache.

J'ai trouvé un exemple d'utilisation de mod_rewrite même si je sais qu'il existe un moyen plus simple.

6 votes

Hé, vous dites : "bien que je sache qu'il y a un moyen plus simple"... lequel ? ^_^

0 votes

Si je pouvais trouver les détails, je les posterais. Je ne les trouve pas pour le moment et je n'ai pas le temps de faire une recherche approfondie.

1 votes

C'est bon, merci pour votre aide. Je viens de créer une page php qui génère le téléchargement...

4voto

Colin Pickard Points 23922

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 distinct (l'image) et un serveur Web normal servira le fichier avec des en-têtes de contenu définis de manière à ce que le navigateur lisant le type de contenu décide que le type peut être traité en interne.

Le moyen de forcer le navigateur à ne pas traiter le fichier en interne est de modifier les en-têtes (content-disposition de préférence, ou content-type) afin que le navigateur n'essaie pas de traiter 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 (c'est-à-dire download.php), soit en configurant le serveur web pour qu'il renvoie des en-têtes différents pour le fichier que vous voulez télécharger. Vous pouvez faire cela sur une base par répertoire sur le serveur web, ce qui vous permettrait de vous en sortir sans écrire aucun php ou javascript - il suffit d'avoir toutes vos images à télécharger à cet endroit.

1 votes

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 content-disposition.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X