web-dev-qa-db-fra.com

(HTML) Téléchargez un fichier PDF au lieu de les ouvrir dans le navigateur lorsque vous cliquez dessus.

Je me demandais comment créer un lien de fichier PDF téléchargeable au lieu de les ouvrir dans le navigateur? Comment cela se fait-il en HTML? (Je suppose que c'est fait via javascript ou autre chose).

93
404Error

Vous ne pouvez pas faire cela avec HTML. C'est une solution basée sur un serveur. Vous devez diffuser le fichier pour que le navigateur déclenche la boîte de dialogue de sauvegarde.

Je conseillerais de ne pas le faire. La manière dont un utilisateur interagit avec un PDF devrait être laissée à l'utilisateur.

MISE À JOUR (2014):

Alors ... cette réponse reçoit encore beaucoup de votes négatifs. Je suppose qu'une partie de cela est que cela a été répondu il y a 4 ans et, comme le souligne Sarim, il existe maintenant l'attribut HTML 5 download qui peut gérer cela.

Je suis d’accord et pense que la réponse de Sarim est bonne (ce devrait probablement être la réponse choisie si le PO revient un jour). Cependant, cette réponse reste le moyen le plus fiable de la gérer (comme le souligne la réponse de Yiğit Yener et - curieusement - les gens sont d’accord avec). Bien que l'attribut de téléchargement ait obtenu un support, il est toujours inégal:

http://caniuse.com/#feat=download

34
DA.

Avec html5, c'est possible maintenant. Définir un "téléchargement" attr dans l'élément.

<a href="http://link/to/file" download="FileName">Download it!</a>

Source: http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download

116
Sarim

Cela n'est possible qu'avec la définition d'un en-tête de réponse http par le code côté serveur. À savoir;

Content-Disposition: attachment; filename=fname.ext
77
Yiğit Yener

Vous devez modifier les en-têtes http envoyés. En fonction de votre serveur, vous pouvez modifier votre fichier .htaccess comme suit:

<FilesMatch "\.(?i:pdf)$">
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</FilesMatch>
13
php guy

vous devrez utiliser un script PHP (ou un autre langage côté serveur pour cela)

<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');

// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf
readfile('original.pdf');
?>

et utilisez httacces pour rediriger (réécrire) vers le fichier PHP au lieu du fichier pdf

9
beardhatcode

Vous pouvez utiliser

Response.AddHeader("Content-disposition", "attachment; filename=" + Name);

Découvrez cet exemple:

http://www.codeproject.com/KB/aspnet/textfile.aspx

Cela vaut pour ASP.NET. Je suis sûr que vous pouvez trouver des solutions similaires dans tous les autres langages côté serveur. Cependant, il n'y a pas de solution javascript à ma connaissance.

8
mihsathe

Sans l'attribut html5, on peut y arriver en utilisant php:

Créez un fichier php nommé download.php avec ce code:

<?php
ob_start();
$file = "yourPDF.pdf"

if (file_exists($file)) 
{
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit();
}

Maintenant, si vous voulez commencer à télécharger automatiquement le pdf, écrivez ce javascript:

<script>window.location = "download.php";</script>

Si vous voulez que cela fonctionne sur un lien, utilisez ceci ...

<a href='javascript:window.location = "download.php"'>
    Download it!
</a>
4
hlozancic

Lorsque vous souhaitez télécharger directement une image ou un fichier pdf à partir du navigateur au lieu de l'ouvrir dans un nouvel onglet, vous devez définir en javascript la valeur suivante pour l'attribut download de create dynamic

    var path= "your file path will be here"; 
    var save = document.createElement('a');  
    save.href = filePath; 
    save.download = "Your file name here"; 
    save.target = '_blank'; 
    var event = document.createEvent('Event');
    event.initEvent('click', true, true); 
    save.dispatchEvent(event);
   (window.URL || window.webkitURL).revokeObjectURL(save.href);

Pour les nouveaux Chrome, la mise à jour de certains événements ne fonctionne pas. pour que le code suivant soit utilisé

  var path= "your file path will be here"; 
    var save = document.createElement('a');  
    save.href = filePath; 
    save.download = "Your file name here"; 
    save.target = '_blank'; 
    document.body.appendChild(save);
    save.click();
    document.body.removeChild(save);

L'ajout d'enfant et sa suppression sont utiles pour Firefox, navigateur Internet Explorer uniquement. Sur chrome cela fonctionnera sans ajout ni suppression d'enfant

4
Prasad Joshi

Comme le mode html5 (ma réponse précédente) n’est pas disponible dans tous les navigateurs, voici un autre moyen légèrement piraté.

Cette solution nécessite que vous serviez le fichier prévu à partir du même domaine. OR dispose de l'autorisation CORS.

  1. Commencez par télécharger le contenu du fichier via XMLHttpRequest (Ajax).
  2. Créez ensuite un URI de données en codant en Base64 le contenu du fichier et définissez le type de support sur application/octet-stream. Le résultat devrait ressembler à

data:application/octet-stream;base64,SGVsbG8sIFdvcmxkIQ%3D%3D

Maintenant, définissez location.href = data. Cela entraînera le téléchargement du fichier par le navigateur. Malheureusement, vous ne pouvez pas définir le nom de fichier ou l'extension de cette façon. Le fait de jouer avec le type de média pourrait donner quelque chose.

Voir les détails: https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs

2
Sarim

Si vous utilisez HTML5 (et j'imagine que tous les jours l'utilisent), il existe un attribut appelé download.

ex. <a href="somepathto.pdf" download="filename">

ici, filename est facultatif, mais s'il est fourni, il prendra ce nom pour le fichier téléchargé.

2
Akshay

La solution qui a le mieux fonctionné pour moi était celle qui avait été écrite par Nick sur son blog

L'idée de base de sa solution est d'utiliser l'en-tête de serveur Apache et de modifier le fichier .htaccess afin d'inclure une directive FileMatch selon laquelle tous les fichiers * .pdf sont forcés d'agir comme un flux plutôt que comme une pièce jointe. Bien que cela n'implique pas réellement l'édition de HTML (comme dans la question initiale), cela ne nécessite aucune programmation en soi.

La première raison pour laquelle j’ai préféré l’approche de Nick, c’est que cela me permettait de le définir par dossier pour que les fichiers PDF d’un dossier puissent toujours être ouverts dans le navigateur tout en permettant aux autres (ceux que nous aimerions que les utilisateurs modifient et téléchargent à nouveau). être forcé en téléchargement.

J'aimerais également ajouter qu'il existe une option avec les PDF pour poster/soumettre des formulaires remplissables via une API à vos serveurs, mais cela prend un certain temps à mettre en œuvre.

La deuxième raison était que le temps est une considération. Écrire un gestionnaire de fichiers PHP pour forcer la disposition du contenu dans l'en-tête () prendra également moins de temps qu'une API, mais reste plus long que l'approche de Nick.

Si vous savez comment activer un mod Apache et modifier le fichier .htaccss, vous pouvez l’obtenir en 10 minutes environ. Il nécessite un hébergement Linux (pas Windows). Cette approche peut ne pas être appropriée pour toutes les utilisations, car elle nécessite un accès de haut niveau au serveur pour la configuration. En tant que tel, si vous avez dit accès, c'est probablement parce que vous savez déjà comment faire ces deux choses. Sinon, consultez le blog de Nick pour plus d'instructions.

2
Strixy

Le comportement devrait dépendre de la configuration du navigateur pour gérer les différents types MIME. Dans ce cas, le type MIME est application/pdf. Si vous souhaitez forcer le navigateur à télécharger le fichier, vous pouvez essayer d'imposer un autre type MIME aux fichiers PDF. Je recommande contre cela car il devrait être le choix des utilisateurs ce qui se passera quand ils ouvriront un fichier PDF.

1
Aleksi Yrttiaho

Je devais le faire pour les fichiers créés avec des noms dynamiques dans un dossier particulier et desservis par IIS.

Cela a fonctionné pour moi:

  • Dans IIS, accédez à ce dossier et double-cliquez sur En-tête de réponse HTTP.
  • Ajoutez un nouvel en-tête avec les informations suivantes:

    Name: content-disposition Value: attachment

(from: http://forums.iis.net/t/1175103.aspx?add+CustomHeaders+only+for+certain+file+types+ )

1
EricL