2
votes

Chrome ouvre le fichier CSV au lieu de l'enregistrer

J'ai une application PHP qui génère un fichier CSV et redirige l'utilisateur vers une page statique reliant le fichier, juste l'exemple ci-dessous:

https://www.example.com/public_html/static/temp/myfile.csv

Le problème est, Chrome ouvre le fichier au lieu de l'enregistrer. J'ai besoin de Chrome pour enregistrer ce fichier, comme il le ferait avec n'importe quel autre fichier comme un zip ou un mp3, par exemple.

Voici ce que j'ai essayé:

header('location:https://www.example.com/public_html/static/temp/myfile.csv');    
header('Content-Disposition: attachment; filename=myfile.csv'); 

Mais pas de chance, Chrome continue d'afficher le contenu de myfile.csv au lieu de le télécharger.

Des idées?

Merci


13 commentaires

le Content-Disposition n'a aucune signification ici dans ce traitement de requête, il doit être dans les en-têtes de réponse de la prochaine requête à /public_html/static/temp/myfile.csv make Assurez-vous que la deuxième requête a 'Content-Disposition: attachment; dans les en-têtes de réponse


C'est faux à la fois en termes de convention et de logique: les en-têtes HTTP doivent avoir la casse appropriée et un espace après les deux points. Et appeler https: //domain/file.csv n'exécutera nulle part votre code PHP. En plus: la redirection d'une requête HTTP (via Location: ) permet au client de demander le nouvel URI, et non de transmettre au serveur le contenu de la cible. Solution: servez un fichier PHP qui produit votre CSV.


@AmigoJack Lorsque je redirige vers le fichier CSV, le code PHP est déjà exécuté et le fichier prêt à être téléchargé


@Accountant م Je n'ai pas vraiment saisi l'idée, pouvez-vous expliquer plus?


@delphirules si la requête adressée à /public_html/static/temp/myfile.csv a le Content-Disposition: attachment; dans les en-têtes de réponse, Chrome téléchargera le fichier au lieu de en l'ouvrant, assurez-vous que la réponse contient cet en-tête de l'onglet réseau Chrome dans les outils de développement.


@Accountant م Mais j'envoie déjà cet en-tête avec celui de l'emplacement?


@delphirules Non, c'est une demande différente. La première requête est adressée à votre fichier PHP qui génère le fichier csv, enregistrez-le sur disque et redirige le navigateur vers /myfile.csv . La deuxième requête est adressée à /myfile.csv et doit avoir le Content-Disposition: attachment; dans les en-têtes de réponse


@Accountant م Dans l'exemple ci-dessus, lorsque je redirige vers le fichier CSV, il est déjà généré par un script PHP précédent. Je veux juste rediriger l'utilisateur vers le fichier CSV et le forcer à être téléchargé, pas afficher sur le navigateur


@delphirules 1- Cet extrait de code dans la question se trouve dans le fichier PHP qui génère le fichier csv, non? 2- Quelle est l'URL du fichier PHP qui génère le fichier csv, et quelle est l'URL du fichier statique csv?


@Accountant م L'URL qui génère le CSV est comme ' example.com/controller/report.php '. Dans ce script, je génère le fichier CSV et je redirige vers le CSV en utilisant le code que j'ai fourni dans la question.


@delphirules Ok ce plan obligera le navigateur à faire 2 requêtes , le premier est au fichier report.php qui générera le fichier csv et l'enregistrera sur le disque et redirigera le navigateur au fichier statique, la deuxième requête est adressée au fichier statique à myfile.csv , vous avez besoin de Content-Disposition: attachment; dans la réponse de la deuxième demande à myfile.csv pas la première à report.php . ouvrez l'onglet réseaux et voyez cela se produire en action et assurez-vous que la deuxième demande contient Content-Disposition: attachment; dans la réponse.


@Accountant م D'une manière ou d'une autre, le navigateur ne reçoit pas l'en-tête Content-Disposition: (


@delphirules OK, pouvez-vous faire ces 3 tests, 1- va ouvrir Chrome ce fichier csv ou le télécharger? 2- Chrome et Firefox ont-ils le même comportement? ou c'est juste Chrome? 3- vérifiez l'en-tête Content-Type de la réponse de la deuxième requête dans votre application, qu'est-ce que c'est?


3 Réponses :


0
votes

Avec html5, vous pouvez définir l'attribut "téléchargement" dans un élément.

Téléchargez-le! Source: http://updates.html5rocks.com/ 2011/08 / Téléchargement-de-ressources-en-HTML5-a-download


2 commentaires

Merci, mais je n'ai pas vraiment d'élément qui renvoie au fichier CSV; l'utilisateur clique sur un bouton qui déclenchera un script PHP puis ce script génère le fichier CSV et redirige


Lien plus officiel: w3.org/TR/html51/ textlevel-semantics.html # the-a-element



1
votes

Votre argumentation dans les commentaires a un malentendu sans fin: l'en-tête Location demande à n'importe quel client d'effectuer une nouvelle requête à l'URI donné. Avec cela, la demande actuelle est terminée. Les en-têtes de la requête actuelle (c'est-à-dire Content-Disposition ) ne sont pas magiquement reportés à la requête suivante.

En d'autres termes: votre "page statique renvoyant au fichier, juste l'exemple ci-dessous" doit envoyer l'en-tête souhaité.

En fin de compte, je suis sûr que ce n'est pas non plus un problème de Chrome, mais cela affecte tous les navigateurs Internet, car ils détectent facilement les données CSV sous forme de texte, ce qui permet de rendre / afficher ces données au lieu de pouvoir les enregistrer uniquement dans un fichier.


0 commentaires

-1
votes

Après avoir lutté avec ce problème pendant quelques jours, la seule vraie solution que j'ai obtenue est de compresser le fichier puis de le rediriger vers le fichier ZIP au lieu du CSV. Ce faisant, Chrome téléchargera le fichier ZIP au lieu de l'ouvrir:

header('location:https://www.example.com/public_html/static/temp/myfile.csv.zip');    


1 commentaires

C'est une solution de contournement, pas une solution. Et vous écrivez mal votre instruction d'en-tête.