Télécharger le fichier à partir du serveur angulaire $http.obtenez de l'
Je suis en train de déclencher le téléchargement d'un fichier lorsqu'un utilisateur clique sur "Télécharger le PDF" bouton. Un appel est effectué à l'API qui fait quelques vérifications, puis renvoie le fichier. Je ne veux pas le fichier pour l'ouvrir dans le navigateur. J'ai lu beaucoup de stackoverflow-questions sur la façon de le faire, mais ne peut pas le faire fonctionner. Je reçois le contenu d'un fichier en tant que texte, mais le navigateur ne peut pas enregistrer le fichier, ni me donne le choix de l'enregistrer comme un fichier.
C'est ce que j'ai.
HTML
<button ng-click="apiDownload()">Download PDF</button>
AngularJS contrôleur
$scope.apiDownload = function(){
var config = {
method: 'GET',
url: "/api/download",
headers: {
'Accept': 'application/pdf'
}
};
$http(config)
.success(function(res){
console.log(res);
})
.error(function(res){});
};
PHP API (principalement à partir de ici)
function apiDownloadFile() {
$file_name = "download/test.pdf";
$abs_file_name = realpath(dirname(__FILE__)).'/'.$file_name;
if(is_file($abs_file_name) && file_exists($abs_file_name)) {
//required for IE
if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); }
//get the file mime type using the file extension
switch(strtolower(substr(strrchr($file_name, '.'), 1))) {
case 'pdf': $mime = 'application/pdf'; break;
case 'zip': $mime = 'application/zip'; break;
case 'jpeg':
case 'jpg': $mime = 'image/jpg'; break;
default: $mime = 'application/force-download';
}
header('Pragma: public'); //required
header('Expires: 0'); //no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($abs_file_name)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename='.basename($abs_file_name));
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($abs_file_name)); //provide file size
header('Connection: close');
readfile($abs_file_name); //push it out
exit();
}
}
Je vois ces en-têtes dans les outils de développement chrome:
En-Têtes De Requête
GET /api/download HTTP/1.1
Host: sa.dev
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: application/pdf
If-Modified-Since: 0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
Referer: https://sa.dev/insights
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,da;q=0.6,sv;q=0.4,no;q=0.2,nb;q=0.2
Cookie: ...
En-Têtes De Réponse
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2015 14:27:08 GMT
Server: Apache/2.4.9 (Unix) PHP/5.6.5 OpenSSL/0.9.8zc
X-Powered-By: PHP/5.6.5
Pragma: public
Expires: 0
Cache-Control: must-revalidate, post-check=0, pre-check=0
Last-Modified: Mon, 16 Mar 2015 09:04:06 GMT
Cache-Control: private
Content-Disposition: attachment; filename=test.pdf
Content-Transfer-Encoding: binary
Content-Length: 5501633
Connection: close
Content-Type: application/pdf
- Avez-vous essayé
location.assign
en javascript? ( w3schools.com/jsref/met_loc_assign.asp ). Remarque: Cela ne fonctionne que sur la assez récents navigateurs (basé sur: stackoverflow.com/a/9723787/624590 , bien que pour beaucoup de ces navigateurs sont assez vieux qu'il ne devrait pas être un problème). - Éventuellement, vous pouvez trouver quelques informations utiles ici stackoverflow.com/questions/4545311/...
Vous devez vous connecter pour publier un commentaire.
J'ai résolu ce problème en utilisant Jean Culviner's jQuery.fileDownload de la bibliothèque (voir ce SOI-répondre).
Lors de l'utilisation de jQuery.fileDownload j'ai eu à faire ajouter deux choses à mon code.
De définir un cookie
setcookie('fileDownload', "true", NULL, '/');
Set-Cookie: fileDownload=true; path=/
Appel
$.fileDownload('/api/download');
de js. Et supprimer l'utilisation de angulaire $http.Voir ce blog pour plus d'informations sur comment faire pour utiliser jQuery.fileDownload.
Si quelqu'un a une solution pour le faire sans l'aide d'une bibliothèque jQuery, n'hésitez pas à poster une réponse.
Fonctionne très bien
Authorization
etc.