Force Download via Ajax et PHP

Je veux créer un fichier téléchargé qui permet le téléchargement Force de JPG. C'est mon script php:

<?php header("Pragma: public"); // required header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Description: File Transfer"); header("Content-Type: image/jpg"); header('Content-Disposition: attachment; filename="'.basename($GET['a']).'"'); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize(($GET['a'])); readfile(($GET['a']); ?> 

C'est un segment de code de mon code js:

 function downloadFile(a){ document.location = "download.php?a="+ a; } 

Avec cet exemple de code, rien ne se passe. Si j'ajoute le résultat à une balise HTML, cela montre le contenu du fichier.

Toute idée de l'enseignement du navigateur pour télécharger ce fichier?

EDIT: MISE À JOUR DU SCRIPT

Vous ne pouvez pas télécharger de fichiers avec ajax. Donc, si vous avez quelque chose qui devrait arriver sur ajax, vous devriez renvoyer l'URL en réponse et l'appliquer comme document.location = "url" pour démarrer le processus de téléchargement.

Une note ici. Comme je me souviens bien, le navigateur bloque le téléchargement de fichier s'il est lancé non par un clic d'utilisateur. Donc, cela va bien fonctionner:

 .click(function(){ document.location = "download url" }) 

Mais s'il est démarré non par un clic d'utilisateur, il sera bloqué. Alors, codez comme ceci:

 .click(function(){ $.ajax({..., success:function(download_url_from_server){ document.location = download_url_from_server; }}); }) 

Sera bloqué par le navigateur. Donc, si vous souhaitez transmettre certaines données avec une publication, vous pouvez soumettre un formulaire à l'iframe caché ou à la page vierge en utilisant <form target="..." :

  function checkToken(token){ var $form = $("#downloadForm"); if ($form.length == 0) { $form = $("<form>").attr({ "target": "_blank", "id": "downloadForm", "method": "POST", "action": "script.php" }).hide(); $("body").append($form); } $form.find("input").remove(); var args = { a: "checkToken", b: token } for (var field in args) { $form.append($("<input>").attr({"value":args[field], "name":field})); } $form.submit(); } 

Et dans script.php, vous devez exécuter le code de download.php immédiatement, si le jeton est Ok, ou faites un redirection pour télécharger le script:

 header("Location: download.php?a=" . $filename) 

La définition du type mime à l' image/jpeg ne fonctionnera probablement pas. Donc, vous avez besoin d' application/octet-stream place pour forcer le téléchargement.

Remplacez l'en-tête de type de contenu dans votre php par ce qui suit:

 header('Content-Type: application/octet-stream'); 

En outre, une solution agréable au lieu d'utiliser document.location est d'injecter un iframe. Utilisez la fonction suivante dans votre rappel de réussite

 function downloadFile(url) { var iframe; iframe = document.getElementById("download-container"); if (iframe === null) { iframe = document.createElement('iframe'); iframe.id = "download-container"; iframe.style.visibility = 'hidden'; document.body.appendChild(iframe); } iframe.src = url; } 

Il semble que vous ayez des erreurs dans votre script. Tout d'abord, la spande correcte pour la variable GET est $ _GET ['a'], et non $ GET ['a']. Le deuxième problème ici est que vous avez des parenthèses d'ouverture supplémentaire, lorsque j'ai copié votre code, j'ai reçu 500 réponses d'erreur du serveur interne. Si nous corrigeons les erreurs, cela semble fonctionner correctement. Essayez simplement la version corrigée de votre code.

 <?php header("Pragma: public"); // required header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Description: File Transfer"); header("Content-Type: image/jpg"); header('Content-Disposition: attachment; filename="'.basename($_GET['a']).'"'); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($_GET['a'])); readfile($_GET['a']); ?> 

Votre approche est juste, et vous ne devez rien faire dans votre rappel AJAX. Apparemment, vous manquez l'en Content-Description: File Transfer tête Content-Description: File Transfer . Ajoutez-le et cela fera apparaître le navigateur dans la boîte de dialogue Enregistrer le fichier (ou simplement enregistrer dans l'emplacement par défaut, en fonction de vos paramètres).

Vous l'avez confus un peu. Comme l'a souligné FAngel, vous ne pouvez pas télécharger de fichiers via AJAX. Ce que vous devez faire est de rediriger l'utilisateur vers une autre page qui contient le code PHP ci-dessus. Ce code PHP devrait alors permettre à l'utilisateur de télécharger le fichier directement. Ce que vous tentez est absolument possible, il vous suffit de l'aborder dans une autre direction, c'est-à-dire pas avec AJAX.