web-dev-qa-db-fra.com

Forcer le téléchargement de fichier avec php en utilisant header ()

Je veux que l'utilisateur puisse télécharger certains fichiers que j'ai sur mon serveur, mais quand j'essaie d'utiliser l'un des nombreux exemples de cela sur Internet, rien ne semble fonctionner pour moi. J'ai essayé le code comme ça:

<?php

$size = filesize("Image.png");

header('Content-Description: File Transfer');
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename="Image.png"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $size);
readfile("Image.png");

J'ai même essayé d'utiliser l'exemple le plus simple que j'ai pu trouver, comme ceci:

<?php
header('Content-type: image/png');
header('Content-Disposition: attachment; filename="Image.png"');
readfile('Image.png');

Lorsque j'ai testé cela, j'ai supprimé tout le code que j'avais et utilisé un fichier vide contenant uniquement ce code pour supprimer les erreurs créées par des sources externes.

Lorsque je regarde dans la console, le fichier est envoyé avec les en-têtes appropriés: i.e

'Content-Disposition: attachment; filename="Image.png"'

Mais la boîte de dialogue de sauvegarde n'est pas affichée.

J'ai également essayé d'utiliser inline au lieu de pièce jointe dans l'en-tête de disposition du contenu, mais cela ne faisait pas de différence non plus. J'ai déjà testé cela dans Firefox 8.0.1 Chrome 15.0.874.121 et Safari 5.1.1.

55
Kerp

Le problème était que j’utilisais ajax pour publier le message sur le serveur. Lorsque j’utilisais un lien direct pour télécharger le fichier, tout fonctionnait bien.

J'ai utilisé cet autre matériau de questions-réponses Stackoverflow, cela a très bien fonctionné pour moi:

4
Kerp

Je suis presque sûr que vous n’ajoutez pas le type MIME en tant que JPEG lors du téléchargement de fichiers:

header('Content-Type: image/png');

Ces en-têtes ne m'ont jamais manqué:

$quoted = sprintf('"%s"', addcslashes(basename($file), '"\\'));
$size   = filesize($file);

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $quoted); 
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $size);
96
Lawrence Cherone

Cela a fonctionné pour moi comme un charme pour télécharger PNG et PDF.

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$file_name.'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file_url)); //Absolute URL
ob_clean();
flush();
readfile($file_url); //Absolute URL
exit();
14
Farhan Sahibole

son travail pour moi

$attachment_location = "filePath";
if (file_exists($attachment_location)) {

    header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
    header("Cache-Control: public"); // needed for internet Explorer
    header("Content-Type: application/Zip");
    header("Content-Transfer-Encoding: Binary");
    header("Content-Length:".filesize($attachment_location));
    header("Content-Disposition: attachment; filename=filePath");
    readfile($attachment_location);
    die();
} else {
    die("Error: File not found.");
}
2
Mhmd

Basé sur réponse de Farhan Sahibole :

        header('Content-Disposition: attachment; filename=Image.png'); 
        ob_clean();

        readfile($file);

C'est tout ce dont j'avais besoin pour que cela fonctionne. J'ai enlevé tout ce qui n'est pas nécessaire pour que cela fonctionne.

La clé est d'utiliser ob_clean();

2
Robin van den Hurk