picture picture
février 4, 2010 PHP 50 Commentaires

Forcer le téléchargement des liens PDF

Rien n’est plus agaçant que de lancer l’ouverture d’un fichier PDF en cliquant sur un lien dans une page web… d’autant plus désagréable lorsque le fichier en question est lourd, ce qui est souvent le cas pour ce type de fichiers (catalogues ou manuels par exemples)
Or c’est pourtant l’action par défaut que proposent la plupart des navigateurs…
. Il existe une solution simple pour forcer le téléchargement :

Cliquez ici pour voir un exemple sans forcer le téléchargement

Cliquez ici pour voir un exemple en forçant le téléchargement

Première étape :

mettre dans le même dossier que le fichier PDF (test.pdf pour l’exemple) un fichier PHP intitulé : telecharge.php :

<?php
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=$_GET[pdf]");

// On teste l'extension souhaitée pour plus de sécurité (ici c'est un PDF)
if(strtolower(substr(strrchr($_GET['pdf'],'.'),1)) != 'pdf') {
  header("location:../index.html");
  exit;
}

// sinon on lance le téléchargement
else 
  readfile($_GET['pdf']);
?>
									

2ème étape :

On crée un lien sur le fichier telecharge.php :

<a href="[chemin vers le fichier]/telecharge.php?pdf=test.pdf">Cliquez ici pour voir un exemple en forçant le téléchargement</a>
									

Et voilà… c’est tout :)

NB : si vous utilisez un CMS de type blog ou site open-source, notez que cette méthode présente une faille de sécurité par laquelle un visiteur mal intentionné peut récupérer les identifiants d’accès de votre base des données par exemple. Je vous laisse donc juge de l’opportunité de son utilisation selon le degrés de confidentialité des données de votre site.

50 Responses to “Forcer le téléchargement des liens PDF”

50 Commentaires

  1. mimn dit :

    pas bien

  2. webtolosa dit :

    Merci Joan : ta méthode permet effectivement d’améliorer sensiblement la sécurité du script
    J’ai simplement remplacé les expressions régulières par un test d’extension PHP.

  3. Joan dit :

    ATTENTION : il y a une grosse faille de sécurité facile à exploiter et à corriger !

    Ce script permet de télécharger tous les fichiers pressant sur votre site.
    Il suffit de remplacer ‘test.pdf’ par le chemin et nom de fichier à télécharger.

    Le stricte minimum est de vérifier que $_GET[‘pdf’] se termine bien par .pdf
    Si on veut être un peu plus stricte on peut à l’aide des expression rationnelles vérifier que le nom de fichier ne comporte que des caractères alphanumérique, il suffit de rajouter la ligne :

    if(! preg_match(‘^[[:alnum:]-_. ]*\.pdf$’, $_GET[‘pdf’])){
    exit() ;
    }

    La règle la plus importante pour la sécurité d’un site est de toujours vérifier le contenu de $_GET et de $_POST

    Sinon, c’est une très bonne astuce, mais il faut juste rajouter une ligne pour la rendre sécurisée.

    Cordialement,
    Joan

  4. webtolosa dit :

    ce n’est pas du HTML mais du… PHP ! Apparemment tu as un problème de lien, vérifie ton URL (file not found)

  5. vilto dit :

    The requested URL /www/img/download.php was not found on this server.

    Aucune méthode ne marche même l’ouverture non forcée avec un simple bout d’html…

    Cela peut-il venir de l’h »bergement OVH ?

  6. gab dit :

    Merci pour ce tuto.
    Même une buse comme moi y est parvenu
    Pour faire un php, créer un .txt et l’ouvrir avec notepad++ (click droit sur le txt)Après avoir crée le php en ajoutant les lignes de code dedans ajouter cette ligne à votre cible avant le nom du fichier
    telecharge.php?pdf=
    Et ça marche

  7. Frédéric dit :

    Bonjour,
    Impeccable, cette solution, surtout pour remplir un formulaire pdf, ce qui semble impossible avec les lecteurs pdf intégrés aux navigateurs.
    Merci.

  8. jean-luc dit :

    J’ai galéré plusieurs heures avant de trouver votre script qui fonctionne bien. Jai juste un petit problème, lorsque la boite de chargement s’ouvre, je n’ai pas le nom du fichier à télécharger ou à ouvrir mais l’information ARRAY. sinon, l’opération se déroule normalement. Si vous pouvez jzter un coup d’oeil, sur mon site, bouton OUVRAGES télécharger

    Un grand merci tout de même pour l’info

  9. Bugzbunny dit :

    Merci ! C’est pas forcément ce que j’attendais, mais je vais voir si je trouve la solution là bas ^^Bonne soirée !

  10. Bugzbunny dit :

    http://hpics.li/ac97f20

    SI ça peut aider à m’aider :)

  11. Bugzbunny dit :

    Mamp c’est Wamp pour Mac… Et il est fonctionel :)

  12. webtolosa dit :

    C’est Wamp et pas « Mamp ».
    Tu as peut-être lancé les services mais tu n’es pas connecté sur le serveur.
    Pour ça fait
    – vérifie que les services sont bien lancés (l’icône Wamp doit être verte, à côté de l’horloge ds la barre des taches)
    – ensuite fait un simple clic gauche sur cette icône et sur e menu qui s’ouvre clique sur « localhost ». Tu n’auras pas besoin de « renommer » l’URL

    Tuto : http://www.siteduzero.com/informatique/tutoriels/concevez-votre-site-web-avec-php-et-mysql/sous-windows-wamp

  13. Bugzbunny dit :

    Je suis certain que mon problème est minime, mais n’ayant aucune connaissance du php, certaines des solutions évoquées plus haut doivent m’échapper..

  14. Bugzbunny dit :

    L’URL est

    file:///Applications/MAMP/htdocs/Index.html

    et si j’essaye dela renommer (sans trop comprendre ce que ej fais, il faut bien le dire) ça m’affiche une page d’erreur.

  15. Bugzbunny dit :

    J’ai MAMP de lancé, et mon firefox n’accepte pas le renommage dans la barre d’adresse .. du moins il m’affiche une page d’erreur !

  16. webtolosa dit :

    Quelle est la question ? As-tu suivi le tuto ci-dessus ?

  17. webtolosa dit :

    tu as oublié de lancer ton serveur local :) Installe Wamp Server par exemple, si ce n’est pas fait, et lance le.
    L’URL de ton navigateur doit être http://localhost/monsite.com

  18. Bugzbunny dit :

    Bonjour,

    je débute en hmtl et js, mais je m’en sors avec les infos trouvé sur le web.
    Pour ce qui est du php c’est une autre histoire.
    En effet, lorsque j’applique ton « tutoriel », mon navigateur me propose effectivement de télécharger un fichier, mais pas le pdf.
    Il me propose de télécharger « telecharge.php ».

    Wtf svp? :/

  19. Red le Renard dit :

    « Quel » article, et non pas « Quelle », voilà qui est corrigé.

  20. Red le Renard dit :

    Quelle article simple, laconique et direct !

    opération réussie en un tour de main, merci !

  21. philippe dit :

    3 minutes pour lire l ‘article, 2 minutes pour le mettre en pratique,
    1 minute pour le teste.
    Que dire de plus à part bravo.

  22. elbisounours dit :

    ^^ Enjoy, merci pour cette astuce fort utile !

    Les formulaire .pdf intéractifs ne pouvant plus être remplis directement online depuis Firefox 18 qui n’utilise plus nativement Adobe Acrobat pour lire les .pdf (une histoire de sécurité cetainement ?), idem soucis avec Chrome et IE… votre solution est pour moi LA solution !

  23. webtolosa dit :

    ^^ quand on met un PDF en téléchargement libre sur son site on ne cherche pas essentiellement à le cacher ;-D

  24. Alfred musset dit :

    Bonjour,

    Il n’y aurait un gros soucis de sécurité dans ce script par hasard ?
    Le philtre $_GET, non ?

    Codialement.

  25. Merci pour ce petit script php très ingénieux et que j’ai intégré sans problème dans un site en Joomla.
    D’autant plus utile que certains navigateurs ouvrent les fichiers pdf mais leur configuration ne permet pas forcément d’enregistrer ou d’imprimer, à moins d’aller farfouiller un peu partout…
    Ce qu’un utilisateur non averti ne fera pas. :?

  26. Shoubacca dit :

    Merci, c’est simple et efficace!!! ça s’applique d’ailleurs à tous types de fichiers pour peut que l’on change les extensions dans le file php :-)

  27. sylvie dit :

    Super ! Merci pour ce code

  28. rogers75 dit :

    LE FICHIER « telecharger.php (ne pas oublier de créer la balise d’ouverture et fermeture de la page php…)

    session_start();
    $fichier_a_telecharger = $_SESSION[‘fichier_a_telecharger’];
    $term = $_SESSION[‘term’];
    $type = $_SESSION[‘type’];

    header(« Content-type: $type »);
    header(« Content-Disposition: attachment; filename=$_GET[$term] »);
    readfile($_GET[$term]);

  29. rogers75 dit :

    Bon, ça marche pas !!! Le modérateur trouvera la solution :-) Merci.

  30. rogers75 dit :

    OUpsss, le lien a été converti…
    Je le saisi autrement (il faudra supprimer les *)

    // le lien
    echo « télécharger »;

  31. rogers75 dit :

    Ma petite contribution après avoir trouvé votre excellent bout de code…
    La même chose, mais pour plusieurs types de fichiers. Dans mon exemple, cela suppose que la page dans laquelle se trouve le lien soit en php (ou html mais reconnue comme du php en modifiant le fichier apache) pour transmettre des variables en session :

    SUR LA PAGE DANS LAQUELLE SE TROUVE LE LIEN :

    // on cherche l’extension du fichier à télécharger
    $term = strrchr(basename($fichier_a_telecharger), « . »);
    switch($term) {
    case « .gz »: $type = « application/x-gzip »; break;
    case « .tgz »: $type = « application/x-gzip »; break;
    case « .zip »: $type = « application/zip »; break;
    case « .pdf »: $type = « application/pdf »; break;
    case « .png »: $type = « image/png »; break;
    case « .gif »: $type = « image/gif »; break;
    case « .jpg »: $type = « image/jpeg »; break;
    case « .txt »: $type = « text/plain »; break;
    case « .htm »: $type = « text/html »; break;
    case « .html »: $type = « text/html »; break;
    default: $type = « application/octet-stream »; break;
    }
    $term = substr($term, 1);// on supprime le . avant l’extension
    // les variables en session
    $_SESSION[‘fichier_a_telecharger’] = $fichier_a_telecharger;
    $_SESSION[‘term’] = $term;
    $_SESSION[‘type’] = $type;
    // le lien
    echo « télécharger le fichier« ;

    ON CREE ENSUITE LE FICHIER « telecharger.php » (DANS LE MËME DOSSIER QUE LES FICHIERS A TELECHARGER)

    On peut aussi préférer transmettre les variables autrement que par sessions…

  32. webtolosa dit :

    As tu essaye de l’enregistrer sous une version plus ancienne ? Par défaut je crée toujours mes PDF pour être lus avec adobe 6…

  33. tsiory dit :

    slt!j’arrive a ouvrir le fenetre de telechergement mais le problem c’est que une fois le fichier telecharger je ne peut plus la lire.aide moi svp.

  34. webtolosa dit :

    @EMMAN RMS : fais un petit effort, lis ! Tout est expliqué dans le post ci-dessus ^^

  35. EMMAN RMS dit :

    he! le pro vous moij’utilisele html comment dois je faire pour force le télechargement de fichier pdf ou pps.
    vous pouvez m’envoyez le code sous mon adresse E-mail.

    Merci à tous.

  36. MERCI dit :

    MERCI!!!!!!!
    bon sang c’était pas compliqué ça fais 2h que je cherche ça :evil: !

    encore merci :D

  37. Roy dit :

    Bonjour,

    Merci pour cette astuce simple (que j’ai mis un peu de temps à comprendre quand même j’avoue). Tu m’as épargné bien des recherches sur internet pour forcer un téléchargement et maintenant mon site est un cran plus pro ^^. Merci!

  38. Ed dit :

    J’ai essayé, connais le html et le css mais rien en php, suivi les consignes et ça marche impec !
    Merci !

  39. Misterdan dit :

    merci de la précision et article très intéressant.

  40. webtolosa dit :

    Bonjour Daniel,
    il n’y a pas de scripts sans risques … mais celui-ci me semble nettement moins dangereux que n’importe quel formulaire de base. Regarde cet article : http://goo.gl/EeXqB, tu y trouveras 90% des failles exploitées par 90% des hackers. Ça devrait suffire à sécuriser tes sites, à moins que tu ne développes pour le pentagone …!

  41. Misterdan dit :

    merci bien,

    après avoir essayé différents scripts php plus compliqués les uns que les autres et qui me donnaient, au mieux, un pdf corrompu, enfin un tout simple et qui fonctionne xD
    cela dit, en cherchant je suis souvent tombé sur des mises en garde concernant la possibilité de hacker par le biais d’un téléchargement forcé (télécharger d’autres fichiers avec les connexion bdd par ex), est-ce que celui ci est sûr ? que peut-on lui ajouter pour renforcer la sécurité ??

  42. Gérald dit :

    Merci,
    Depuis quelques jour j’étais confronter aux aberrations des navigateurs lors de demande de téléchargement (http) de .pdf et enfin, la solution.

    Merci.

  43. Bastos dit :

    Merci pour l’astuce :smile:

    C’est simple mais encore faut-il y penser :biggrin:

    +++

  44. mehdi dit :

    salut

    merci pour l’astuce, très simple à mettre en place. :biggrin:

    bye

  45. webtolosa dit :

    C’est difficile à dire sans le reste du code.

    Il doit y avoir une erreur PHP quelque part… Si les messages d’erreur ne s’affichent pas sur ton site, met un fichier .htaccess pour les afficher (voir ici : https://www.webtolosa.com/2007/12/09/debuguer-un-site-en-php-avec-un-htaccess/)

    Qu’est ce que tu obtiens comme message d’erreur ?

  46. nounou dit :

    bonjour, j’ai essayer d’adapter votre code à mon script, mais ça ne marche tjrs pas!! j’ai crée le fichier telecherger.pdf et dans ma page php j’ai mis:

    (‘point’)
    $dir = opendir($dir_nom) or die(‘Erreur de listage : le répertoire n\’existe pas’); // on ouvre le contenu du dossier courant
    $ifichier= array(); // on déclare le tableau contenant le nom des fichiers
    $dossier= array(); // on déclare le tableau contenant le nom des dossiers

    while($element = readdir($dir)) {
    if($element != ‘.’ && $element != ‘..’ && $element != ‘index.php’) {
    if (!is_dir($dir_nom.’/’.$element)) {$fichier[] = $element;}
    else {$dossier[] = $element;}
    }
    }

    closedir($dir);

    $hide = Array(‘.’,’..’);
    if(!empty($dossier)) {
    rsort($dossier); // pour le tri croissant, rsort() pour le tri décroissant
    echo « Voici les dossiers accessibles de la ‘$dir_nom’ : \n\n« ;

    echo « \t\t\n »;

    foreach($dossier as $lien){
    if(in_array($lien, $hide))
    continue;
    echo « \t\t\t$lien\n »;

    }
    //echo « \t\t »;
    }

    /*if(!empty($fichier)){
    sort($fichier);// pour le tri croissant, rsort() pour le tri décroissant
    echo « Liste des divers fichiers en hebergement temporaire: \n\n »;
    echo « \t\t\n »;
    foreach($fichier as $lien) {
    echo  »
    \t\t\t$lien\n
    Vide
    « ;
    echo filesize(image.’/’.$lien);
    echo »
    Telecharger« ;
    }
    echo « \t\t »;
    }
    */

    /*if(!empty($fichier)){
    sort($fichier);// pour le tri croissant, rsort() pour le tri décroissant
    echo « Voici les fichiers accessibles de la ‘$dir_nom’ : \n\n« ;
    echo « \t\t\n »;
    foreach($fichier as $lien) {
    echo « \t\t\t$lien\n »;
    }
    echo « \t\t »;
    }*/
    ?>
    télécharger arbre.pdf
    svp , st ce que vous pouvez m’aider à confuser ces deux script pour qu’il marche, merci d’avance :sad:

  47. Capcorne dit :

    Salut,

    Voilà une astuce intéressante, je vois que je ne suis pas le seul à maudire la lecture de pdf dans les navigateurs :biggrin:

    Merci

  48. dada dit :

    Merci, c’est cool :cool:

Commentaire

Name

Mail (ne sera pas publié)

Website

Laisser ces deux champs tels quels :
:D :-) :( :o 8O :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: