web-dev-qa-db-fra.com

Télécharger le fichier pdf à partir de la réponse ajax

J'essaie de faire télécharger par le navigateur un fichier pdf reçu d'une réponse ajax.

Inspiré par Télécharger le fichier pdf en utilisant jquery ajax Je simule un événement de clic/téléchargement comme celui-ci:

    var req = new XMLHttpRequest();
    req.open("POST", "/servicepath/Method?ids=" + ids, true);
    req.responseType = "blob";
    req.onreadystatechange = function () {
        if (req.readyState === 4 && req.status === 200) {
            var blob = req.response;
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = "PdfName-" + new Date().getTime() + ".pdf";
            link.click();
        }
    };
    req.send();

Malheureusement, cela ne fonctionne que dans Chrome, mais pas Firefox + IE. Rien ne se passe lorsque j'essaie de le déclencher dans les deux derniers navigateurs.

Le script et le balisage sont placés dans une iframe en raison de l'héritage d'un CMS, mais je ne sais pas si cela a une influence a.

Une idée sur la façon de l'optimiser pour tous les navigateurs modernes?

10
donpedroper

Une idée sur la façon de l'optimiser pour tous les navigateurs modernes?

Oui, je peux vous donner une solution testée sur Windows 10 avec IE11, Firefox 47 et Chrome 52. Rien pour Microsoft Edge pour le moment.

Au début, vous devez distinguer si vous êtes sur IE ou les deux autres navigateurs. Ceci parce que sur IE11, vous pouvez utiliser:

window.navigator.msSaveBlob(req.response, "PdfName-" + new Date().getTime() + ".pdf");

Pour les deux autres navigateurs, votre code fonctionne sur Chrome mais pas sur Firefox car vous n'avez pas ajouté l'élément au corps du document.

Le code corrigé est donc:

var req = new XMLHttpRequest();
req.open("POST", "/servicepath/Method?ids=" + ids, true);
req.responseType = "blob";
req.onreadystatechange = function () {
  if (req.readyState === 4 && req.status === 200) {

    // test for IE

    if (typeof window.navigator.msSaveBlob === 'function') {
      window.navigator.msSaveBlob(req.response, "PdfName-" + new Date().getTime() + ".pdf");
    } else {
      var blob = req.response;
      var link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = "PdfName-" + new Date().getTime() + ".pdf";

      // append the link to the document body

      document.body.appendChild(link);

      link.click();
    }
  }
};
req.send();
15
gaetanoM

Cette version fonctionnera dans tous les navigateurs modernes:

var req = new XMLHttpRequest();
req.open("POST", "/servicepath/Method?ids=" + ids, true);
req.responseType = "blob";
req.onreadystatechange = function () {
    if (req.readyState === 4 && req.status === 200) {
        var filename = "PdfName-" + new Date().getTime() + ".pdf";
        if (typeof window.chrome !== 'undefined') {
            // Chrome version
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(req.response);
            link.download = "PdfName-" + new Date().getTime() + ".pdf";
            link.click();
        } else if (typeof window.navigator.msSaveBlob !== 'undefined') {
            // IE version
            var blob = new Blob([req.response], { type: 'application/pdf' });
            window.navigator.msSaveBlob(blob, filename);
        } else {
            // Firefox version
            var file = new File([req.response], filename, { type: 'application/force-download' });
            window.open(URL.createObjectURL(file));
        }
    }
};
req.send();

J'essayais d'obtenir également une version pour safari mais cela n'a pas si bien fonctionné. J'essaierai de continuer à enquêter et de donner une solution pour cela aussi.

18
Dekel