web-dev-qa-db-fra.com

PDF Résultats de génération dans ERR_INVALID_RESPONSE dans Chrome

Lors de la génération d'un PDF dans le navigateur par programmation (via PHP), le PDF rendu s'affiche correctement dans Firefox et Safari, mais Chrome renvoie un ERR_INVALID_RESPONSE. C'est un PDF valide - peut être ouvert localement avec Adobe Reader/Preview une fois enregistré à partir des navigateurs de travail, et s'ouvrira même dans Chrome une fois que PDF sera enregistré à partir d'un autre navigateur.

Le fichier PDF est en cours de lecture via file_get_contents(), reçoit un horodatage actuel et est ensuite transmis au navigateur. Une solution de contournement consisterait à enregistrer le fichier dans un emplacement temporaire et à rediriger l'utilisateur (pour Chrome, au moins), mais ce n'est pas idéal.

Je l'ai recherché et n'ai pu trouver rapports de bogues datant de 2008 .

J'ai une idée que c'est une erreur d'en-tête. Une fois le PDF généré, les en-têtes suivants sont envoyés au navigateur (fonctionnant à nouveau correctement dans FF, Safari et IE):

    header('Content-type:application/pdf');
    header("HTTP/1.1 200 OK");

J'ai également essayé d'ajouter les en-têtes suivants après avoir recherché sur Stack Overflow, mais en vain:

    header("Content-Transfer-Encoding: binary");
    header('Accept-Ranges: bytes');

Y a-t-il des en-têtes manquants dont Chrome a besoin? Quelqu'un a-t-il de l'expérience pour afficher des fichiers PDF générés dynamiquement dans Chrome?

EDIT: L'une de mes questions les plus importantes est de savoir ce qui pourrait faire que cela fonctionne correctement localement dans Chrome, mais ne fonctionnerait pas sur un environnement de serveur.

12
Andrew Klatzke

Je tiens à remercier tout le monde pour leurs réponses.

Il s'avère que cela n'était pas lié aux en-têtes. Après avoir tenté de modifier/supprimer des en-têtes de diverses manières (détection de l'encodage, essai avec et sans longueur de contenu, etc.), nous avons décidé de creuser dans les journaux httpd plus profonds pour voir si quelque chose se résolvait différemment pour Chrome.

Il s'avère que mod_sec Sur notre serveur marquait la demande (uniquement de Chrome pour une raison quelconque) comme une tentative d'attaque par injection de fichier et renvoyait une réponse 403 interdite. Chrome l'a affiché en tant que ERR_INVALID_RESPONSE Plutôt qu'en 403.

Le nom d'hôte du CDN était présent dans la demande (nous avons effectué de nombreuses vérifications au niveau du point de terminaison pour nous assurer que le fichier était bien une ressource autorisée) et, à la place, nous construisons l'URL sur le serveur.

5
Andrew Klatzke

Dans mon cas, j'ai dû ajouter ces 2 paramètres aux en-têtes parce que wordpress envoyait du code 404 car il ne l'a pas fait reconnaître l'url de ma fonction php:

header("Content-type: application/pdf",true,200);

comme indiqué dans ce réponse sur wordpress.stackexchange .

Cela oblige les en-têtes à remplacer (2nd param true) le code d'état 404 généré par wordpress car il ne reconnaît pas l'URL personnalisée et définit 200 OK (3rd param 200).

Donc ça a fini par être quelque chose comme ça:

$pdf_name = "test.pdf";
$pdf_file = "/absolute/path/to/my/pdfs/on/my/server/{$pdf_name}";
header('Content-type: application/pdf',true,200);
header("Content-Disposition: attachment; filename={$pdf_name}");
header('Cache-Control: public');
readfile($pdf_file);
exit();
8
Cyberdelphos

Essaye ça

<?php
$filename = 'Physical Path to PDf file.pdf';
$content = file_get_contents($filename);

header("Content-type:application/pdf");

// It will be called downloaded.pdf
header("Content-Disposition:inline;filename='".basename($filename)."'");   
header('Content-Length: '.strlen( $content ));

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

<html>
<body>
...
...
...

Assurez-vous que le code d'en-tête ci-dessus est appelé avant la sortie de PHP est envoyé au navigateur.

6
Alpesh Panchal

Je tiens à remercier tout le monde pour leurs réponses.

Il s'avère que cela n'était pas lié aux en-têtes. Après avoir tenté de modifier/supprimer des en-têtes de diverses manières (détection de l'encodage, essai avec et sans longueur de contenu, etc.), nous avons décidé de creuser dans les journaux httpd plus profonds pour voir si quelque chose se résolvait différemment pour Chrome.

Il s'avère que mod_sec sur notre serveur marquait la demande (uniquement depuis Chrome pour une raison quelconque) comme une tentative d'attaque par injection de fichier et renvoyait une réponse 403 interdite. Chrome l'a affiché comme ERR_INVALID_RESPONSE plutôt que 403.

Le nom d'hôte du CDN était présent dans la demande (nous avons effectué de nombreuses vérifications au niveau du point de terminaison pour nous assurer que le fichier était bien une ressource autorisée) et, à la place, nous construisons l'URL sur le serveur.

0
Calixto Adriance