2011-06-13 4 views
0

J'ai un problème avec forcer le navigateur pour télécharger un fichier. J'ai trouvé ce genre de solution mon problème:Problème avec le téléchargement forcé de fichiers avec PHP

header("Content-type: application/force-download"); 
header("Content-Disposition: attachment; filename=$name_of_file"); 
header("Pragma: no-cache"); 
header("Expires: 0"); 
readfile($name_of_file); 
exit; 

Mais après cela, j'ai mon fichier à l'écran. Même cela fait le même résultat:

header('content-type: text/xml'); 
header('Content-Disposition: attachment;filename="$filename"'); 
echo "TEST"; 
exit; 

Où pourrait être un problème?

+2

quel est le problème? –

+0

@sennin Un exemple d'URL démontrant le problème pour tout le monde serait très bien. Pouvez-vous en fournir un? Aussi, quel navigateur utilisez-vous? Le problème est-il reproductible sur différents systèmes et avec différents navigateurs? – phihag

+2

vous obtiendrez littéralement '$ filename' à la place de la chaîne de nom de fichier réelle dans votre 2ème exemple btw car vous insérez des guillemets simples qui n'incorporent pas la valeur de chaîne' $ filename'. – tradyblix

Répondre

2

Malheureusement, pièce jointe pour le Content-Disposition header field n'est pas très bien supporté. Voilà pourquoi le Content-Type header field value is more important:

Si [le Content-Disposition] en-tête est utilisé dans une réponse avec le type de contenu de l'application/octet-stream, la suggestion implicite est que l'agent utilisateur ne doit pas afficher la réponse, mais entrez directement une boîte de dialogue «save response as ...».

Bien qu'un unknown content type like application/force-download est censé être interprété comme application/octet-stream:

Il est prévu que beaucoup d'autres sous-types de « application » seront définis à l'avenir. Les implémentations MIME doivent à tout le moins traiter les sous-types non reconnus comme équivalents à "application/octet-stream".

Mais vous devriez mieux jouer la sécurité et l'utilisation application/octet-stream explicitement.

1
<?php 
header("Content-Type: application/octet-stream"); 
header("Content-Transfer-Encoding: binary"); 
header("Content-Length: " . filesize($name_of_file)); 
header("Content-disposition: attachment; filename=" . $name_of_file); 
readfile($name_of_file); 
die(); 

1) Il est de votre responsabilité de vous assurer que le fichier existe et est lisible

2) Il peut être utile d'ajouter ob_end_clean(); avant d'envoyer les en-têtes (dans le cas où vous avez envoyé quelque chose déjà)

EDIT: Retirées inutile ; selon les commentaires de porneL, thnx

+0

HTTP est un protocole binaire seulement, 'Content-Transfer-Encoding: binary' est une chose inventée. Content-Length n'est pas supposé avoir ';', et il n'est pas tout à fait correct de mettre ';' après 'application/octet-stream'. Le nom de fichier peut avoir besoin d'être échappé (ce qui, malheureusement, est très compliqué à faire correctement et interopérable). – Kornel

+0

@porneL: Vous avez absolument raison à propos de ';'. J'ai 3 projets complètement fonctionnants où j'envoie des fichiers générés (pdf, xls, csv) et 2 d'entre eux n'ont pas de '' 'dans ces endroits. Mais on a et en quelque sorte cela fonctionne ... Mais je vais modifier ma réponse pour refléter cela. Je ne peux pas vraiment commenter l'en-tête 'Content-Transfer-Encoding: binary' - je l'utilise juste comme il était présent dans une solution quand j'étudiais ce moment il y a quelques années. – LazyOne

0

utiliser Just:

header('Content-Disposition: attachment'); 

et moissonneuse-batteuse avec mod_rewrite ou tel de mettre le nom de fichier correct dans l'URL.

Si vous avez Apache, mais que vous n'utilisez pas mod_rewrite, cela fonctionne aussi;

http://example.com/download_script.php/nice_filename.xml 

Cela provoque l'appel de download_script.php. Les navigateurs verront le nice_filename.xml comme nom de fichier et vous n'aurez pas besoin de l'attribut filename=… très désordonné et peu fiable.

Questions connexes