Comment forcer l'ouverture des fichiers dans le navigateur au lieu du téléchargement (PDF)?


210

Existe-t-il un moyen de forcer l'ouverture des fichiers PDF dans le navigateur lorsque l'option "Afficher le PDF dans le navigateur" n'est pas cochée?

J'ai essayé d'utiliser la balise embed et un iframe, mais cela ne fonctionne que lorsque cette option est cochée.

Que puis-je faire?

Réponses:


419

Pour indiquer au navigateur que le fichier doit être affiché dans le navigateur, la réponse HTTP doit inclure les en-têtes suivants:

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

Pour télécharger le fichier plutôt que le visualiser:

Content-Type: application/pdf
Content-Disposition: attachment; filename="filename.pdf"

Les guillemets autour du nom de fichier sont requis si le nom de fichier contient des caractères spéciaux tels que ceux filename[1].pdfqui pourraient autrement briser la capacité du navigateur à gérer la réponse.

La façon dont vous définissez les en-têtes de réponse HTTP dépendra de votre serveur HTTP (ou, si vous générez la réponse PDF à partir du code côté serveur: votre langage de programmation côté serveur).


13
Pour forcer le téléchargement, j'utilise plutôt Content-Type: application / octet-stream.
Papick G. Taboada

25
@ PapickG.Taboada mais le système de l'utilisateur peut ne pas connaître le type de fichier. Par exemple, certains utilisateurs peuvent avoir opté pour "Toujours ouvrir les fichiers de ce type" pour les fichiers PDF. Peut-être que si vous voulez remplacer les préférences de l'utilisateur, alors le flux d'octets serait la voie à suivre, mais donner le type correct et un nom de fichier suggéré est la manière "correcte" de fournir un téléchargement.
ColinM

2
salut @ColinM Je suis un peu confus ici ... nous avons des problèmes pour rendre le pdf, cela donne juste un texte brouillé. où définissons-nous le Content-Type: application / pdf Content-Disposition: inline; "filename.pdf"? 'cos, nous le téléchargeons en utilisant le code angular-js. Ma question est donc de savoir si le type de contenu doit être défini avant le téléchargement? Et aussi, nous obtenons seulement un lien de l'équipe backend, une URL qui donne le chemin du fichier, que nous ouvrons dans un nouvel onglet en utilisant: window.open (url, '_blank'). Focus ();
Kailas

3
@Kailas Je ne comprends pas ce que vous essayez de faire. La réponse fait référence aux en-têtes qu'un serveur doit envoyer à un client lorsqu'il répond à une requête HTTP pour le fichier PDF. Ces en-têtes n'ont aucun effet sur le téléchargement d'un fichier, vous devez avoir le code derrière l'URL définir les en-têtes chaque fois qu'il est téléchargé par le client.
ColinM

1
@ColinM Merci mon pote, vous l'avez dit correctement, le problème lorsque nous avons débogué était que le type MIME était défini lors du téléchargement des fichiers. Cela devrait être fait par l'équipe back-end. J'ai essayé d'obtenir des codes sur la façon d'ajouter des en-têtes dans le script java, mais sans succès. Merci, car j'ai eu la vraie idée de toi ... :)
Kailas

19

Si vous utilisez HTML5 (et je suppose que tout le monde l'utilise de nos jours), il existe un attribut appelé download .

Par exemple,

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

Voici filenamefacultatif, mais s'il est fourni, il prendra ce nom pour le fichier téléchargé.


2
Si vous contrôlez le code du serveur, vous devez utiliser «pièce jointe» car cela permettra d'utiliser le même code de génération de nom de fichier. Si vous n'avez aucun contrôle sur le serveur, c'est une bonne solution.
Christophe Roussy

C'est une solution brillante au problème cependant, comme toujours, IE nous empêche
Rory McCrossan

1
Il est important de noter que cela ne fonctionne pas sur tous les domaines (par exemple, la politique de même origine fait obstacle). Si vous téléchargez à partir d'un domaine, l'attribut de téléchargement ne fonctionnera pas si le contenu est stocké sur un autre domaine. CORS peut permettre à ce contenu de passer (non testé).
vol7ron

59
C'est littéralement l'opposé de ce que le PO demande :)
Chuck Le Butt

1
Oui compris! : \ J'ai mal compris la question et y ai répondu. Mais beaucoup de gens atterrissent ici pour trouver le contraire, c'est pourquoi ne pas modifier / supprimer la réponse.
Akshay

16

Le type correct est application/pdfpour PDF, non application/force-download. Cela ressemble à un hack pour certains navigateurs hérités. Utilisez toujours le type MIME correct si vous le pouvez.

Si vous contrôlez le code du serveur:

  • Téléchargement forcé / invite: utiliser header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • Le navigateur essaie de l'ouvrir: utilisez header("Content-Disposition", "inline; filename=myfilename.myextension");

Aucun contrôle sur le code du serveur:

REMARQUE: je préfère définir le nom de fichier côté serveur car vous pouvez avoir plus d'informations et utiliser le code commun.


2

Si vous avez Apache, ajoutez ceci au .htaccessfichier:

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

comment ajouter plusieurs extensions? Je veux également ajouter l'extension DOC et XLS. Veuillez me suggérer. Merci d'avance.
Kamlesh

Cela fait le contraire de ce qui est demandé
Quentin

1

Oups, il y avait des erreurs de frappe dans mon post précédent.

    header("Content-Type: application/force-download");
    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=\"".$name."\";");

Si vous ne voulez pas que le navigateur invite l'utilisateur, utilisez "inline" pour la troisième chaîne au lieu de "attachment". Inline fonctionne très bien. Le PDF s'affiche immédiatement sans demander à l'utilisateur de cliquer sur Ouvrir. J'ai utilisé "pièce jointe" et cela invitera l'utilisateur à ouvrir, enregistrer. J'ai essayé de changer l'écrou des paramètres du navigateur, cela n'empêche pas l'invite.


4
Quel post précédent?
Peter Mortensen

0

C'est pour ASP.NET MVC

Dans votre page cshtml:

<section>
    <h4><a href="@Url.Action("Download", "Document", new { id = @Model.GUID })"><i class="fa fa-download"></i> @Model.Name</a></h4>
    <object data="@Url.Action("View", "Document", new { id = @Model.GUID })" type="application/pdf" width="100%" height="800" class="col-md-12">
        <h2>Your browser does not support viewing PDFs, click on the link above to download the document.</h2>
    </object>
</section>

Dans votre contrôleur:

public ActionResult Download(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        return File(model.FilePath, "application/pdf", model.FileName);
    }

public FileStreamResult View(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        FileStream fs = new FileStream(model.FilePath, FileMode.Open, FileAccess.Read);

        return File(fs, "application/pdf");
    }

-1

Bien que ce qui suit fonctionne bien sur Firefox, il ne fonctionne PAS sur les navigateurs Chrome et mobiles.

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

Pour corriger l'erreur des navigateurs Chrome et mobiles, procédez comme suit:

  • Stockez vos fichiers sur un répertoire de votre projet
  • Utilisez la visionneuse Google PDF

Google PDF Viewer peut être utilisé comme suit:

<iframe src="http://docs.google.com/gview?url=http://example.com/path/to/my/directory/pdffile.pdf&embedded=true" frameborder="0"></iframe>

-4

Ouvrez downloads.php à partir du fichier racine.

Passez ensuite à la ligne 186 et modifiez-la comme suit:

        if(preg_match("/\.jpg|\.gif|\.png|\.jpeg/i", $name)){
            $mime = getimagesize($download_location);
            if(!empty($mime)) {
                header("Content-Type: {$mime['mime']}");
            }
        }
        elseif(preg_match("/\.pdf/i", $name)){
            header("Content-Type: application/force-download");
            header("Content-type: application/pdf");
            header("Content-Disposition: inline; filename=\"".$name."\";");
        }

        else{
            header("Content-Type: application/force-download");
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename=\"".$name."\";");
        }

7
Aucune mention qu'ils utilisent PHP. Et si leur back-end est en Python ou .NET?
Maxime Rouiller

1
... parler hors du champ gauche. Il ne dit même pas de quel cadre il parle.
Archonic

-4

Vous pouvez le faire de la manière suivante:

<a href="path to PDF file">Open PDF</a>

Si le fichier PDF se trouve dans un dossier et que ce dossier n'est pas autorisé à accéder directement aux fichiers de ce dossier, vous devez contourner certaines restrictions d'accès aux .htaccessfichiers en utilisant le paramètre de fichier de cette façon:

<FilesMatch ".*\.(jpe?g|JPE?G|gif|GIF|png|PNG|swf|SWF|pdf|PDF)$" >
    Order Allow,Deny
    Allow from all
</FilesMatch>

Mais permettez maintenant juste certain fichiers nécessaires.

J'ai utilisé ce code et cela a parfaitement fonctionné.


Aucune mention qu'ils utilisent Apache. Et s'ils utilisent IIS? Ou Express?
Maxime Rouiller


-7

Voici une autre méthode pour forcer un fichier à afficher dans le navigateur en PHP:

$extension = pathinfo($file_name, PATHINFO_EXTENSION);
$url = 'uploads/'.$file_name;
        echo '<html>'
                .header('Content-Type: application/'.$extension).'<br>'
                .header('Content-Disposition: inline; filename="'.$file_name.'"').'<br>'
                .'<body>'
                .'<object   style="overflow: hidden; height: 100%;
             width: 100%; position: absolute;" height="100%" width="100%" data="'.$url.'" type="application/'.$extension.'">
                    <embed src="'.$url.'" type="application/'.$extension.'" />
             </object>'
            .'</body>'
            . '</html>';

1
headerne fonctionne pas après que vous ayez commencé à sortir le corps de la requête (et il ne retourne pas de chaîne pour la concaténation dans un document HTML)
Quentin

-9

Ouvrez simplement Adobe Reader, menu → ÉditionPréférencesInternet , puis passez en mode navigateur ou pour obtenir des instructions détaillées sur différents navigateurs, essayez Afficher PDF dans le navigateur | Acrobat, Acrobat Reader .


3
Que faire si vous n'utilisez pas AdobeReader ou n'utilisez pas Windows? Votre réponse ne fonctionnera pas. De plus, cela nécessite de demander à l'utilisateur de modifier son paramètre, ce que vous ne pouvez pas faire dans le monde réel.
Clawfire

-12

Si vous créez un lien vers un .PDF, il s'ouvrira dans le navigateur.
Si la case n'est pas cochée, elle doit être liée à un .zip pour forcer le téléchargement.

Si un .zip n'est pas une option, utilisez des en- têtes en PHP pour forcer le téléchargement

header('Content-Type: application/force-download'); 
header('Content-Description: File Transfer'); 

Oui, mais j'ai besoin d'un moyen de forcer l'ouverture dans le navigateur pour ne pas télécharger. Je n'ai aucune idée si c'est possible.
elloalisboa

2
Si vous ne le forcez pas à télécharger, vous le forcez à s'ouvrir dans le navigateur. S'il ne s'ouvre pas dans le navigateur, c'est parce que l'utilisateur a un paramètre spécifique, que vous ne pouvez pas remplacer ou qu'il n'a pas de logiciel de lecture PDF.
Kirk Strobeck,

1
En fait, voyez ma réponse.
Gabriel Ryan Nahmias

21
C'est faux. Il n'y a pas d'application / téléchargement forcé. Vous pouvez également utiliser alskjdsdjk / aljksdlasdj. Le navigateur va télécharger car il ne connaît pas ce type de mime. Le bon type de mime à télécharger serait moi / flux d'
octets
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.