télécharger le fichier en utilisant une requête ajax

je veux envoyer une "demande de téléchargement ajax" quand je clique sur un bouton, donc j'ai essayé de cette façon:

javascript:

var xhr = new XMLHttpRequest();
xhr.open("GET", "download.php");
xhr.send();

de téléchargement.php:

<?
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename= file.txt");
header("Content-Transfer-Encoding: binary");    
readfile("file.txt");
?>

mais ne fonctionne pas comme prévu, je fais comment ? Merci d'avance

67
demandé sur Manuel Di Iorio 2013-12-30 01:35:10

7 réponses

Mise À Jour 27 Avril 2015

et à venir de l'HTML5 scène est le télécharger attribut . Il est pris en charge dans Firefox et Chrome, et bientôt à venir à IE11. Selon vos besoins, vous pouvez l'utiliser à la place d'une demande AJAX (ou en utilisant window.location ) tant que le fichier que vous souhaitez télécharger est de la même origine que votre site.

vous pourriez toujours faire L'AJAX demande/ window.location de secours, à l'aide de JavaScript pour tester si download est pris en charge et si non, de commutation pour appeler des window.location .

réponse Originale à cette question

vous ne pouvez pas avoir une demande AJAX ouvrir l'invite de téléchargement puisque vous devez physiquement naviguer vers le fichier pour inciter au téléchargement. Au lieu de cela, vous pourriez utiliser une fonction de succès pour naviguer à télécharger.php. Ceci ouvrira le téléchargement invite mais ne changera pas la page courante.

$.ajax({
    url: 'download.php',
    type: 'POST',
    success: function() {
        window.location = 'download.php';
    }
});

même si cela répond à la question, il est préférable d'utiliser window.location et d'éviter entièrement la requête AJAX.

88
répondu Steven Lambert 2017-05-23 11:47:25

vous n'avez pas besoin d'ajax pour ça. Si vous définissez simplement "de téléchargement.php" comme le href du bouton, ou, si ce n'est pas un lien d'utilisation:

window.location = 'download.php';

le navigateur doit reconnaître le téléchargement binaire et ne pas charger la page réelle, mais juste servir le fichier comme un téléchargement.

38
répondu Jelle Kralt 2014-04-23 07:25:54

pour que le navigateur télécharge un fichier, vous devez faire la demande comme ça:

 function downloadFile(urlToSend) {
     var req = new XMLHttpRequest();
     req.open("GET", urlToSend, true);
     req.responseType = "blob";
     req.onload = function (event) {
         var blob = req.response;
         var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
         var link=document.createElement('a');
         link.href=window.URL.createObjectURL(blob);
         link.download=fileName;
         link.click();
     };

     req.send();
 }
15
répondu João Marcos 2017-03-15 16:49:46

c'est possible. Vous pouvez faire démarrer le téléchargement à partir d'une fonction ajax, par exemple, juste après le .fichier csv est créé.

j'ai une fonction ajax qui exporte une base de données de contacts à A.fichier csv, et juste après avoir terminé, il démarre automatiquement l' .téléchargement de fichier csv. Ainsi, après que j'obtienne le respetext et que tout est Ok, je redirige le navigateur comme ceci:

window.location="download.php?filename=export.csv";

Mon de téléchargement.fichier php on dirait:

<?php

    $file = $_GET['filename'];

    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: attachment; filename=".$file."");
    header("Content-Transfer-Encoding: binary");
    header("Content-Type: binary/octet-stream");
    readfile($file);

?>

il n'y a aucune mise à jour de page et le fichier commence automatiquement à télécharger.

NOTE - testé dans les navigateurs suivants:

Chrome v37.0.2062.120 
Firefox v32.0.1
Opera v12.17
Internet Explorer v11
13
répondu Pedro Sousa 2014-09-16 11:00:57

Cross browser solution, testée sur Chrome, Firefox, Edge, IE11.

dans le DOM, ajouter un lien caché:

<a id="target" style="display: none"></a>

puis:

var req = new XMLHttpRequest();
req.open("GET", downloadUrl, true);
req.responseType = "blob";

req.onload = function (event) {
  var blob = req.response;
  var fileName = null;
  var contentType = req.getResponseHeader("content-type");

  // IE/EDGE seems not returning some response header
  if (req.getResponseHeader("content-disposition")) {
    var contentDisposition = req.getResponseHeader("content-disposition");
    fileName = contentDisposition.substring(contentDisposition.indexOf("=")+1);
  } else {
    fileName = "unnamed." + contentType.substring(contentType.indexOf("/")+1);
  }

  if (window.navigator.msSaveOrOpenBlob) {
    // Internet Explorer
    window.navigator.msSaveOrOpenBlob(new Blob([blob], {type: contentType}), fileName);
  } else {
    var el = document.getElementById("target");
    el.href = window.URL.createObjectURL(blob);
    el.download = fileName;
    el.click();
  }
};
req.send();
5
répondu leo 2018-04-05 14:05:08
1
répondu Telmo Dias 2015-01-13 10:11:39

décoder un nom de fichier à partir de l'en-tête est un peu plus complexe...

    var filename = "default.pdf";
    var disposition = req.getResponseHeader('Content-Disposition');

    if (disposition && disposition.indexOf('attachment') !== -1) 
    {
       var filenameRegex = /filename[^;=\n]*=((['"]).*?|[^;\n]*)/;
       var matches = filenameRegex.exec(disposition);

       if (matches != null && matches[1]) 
           filename = matches[1].replace(/['"]/g, '');
    }
0
répondu Lumic 2018-05-19 00:01:10