web-dev-qa-db-ja.com

Ajax応答からPDFファイルをダウンロードする

私は、ブラウザにajax応答から受信したpdfファイルをダウンロードさせようとしています。

インスピレーション jquery ajaxを使用してPDFファイルをダウンロード 次のようなクリック/ダウンロードイベントをシミュレートします。

    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();

残念ながら、これはChromeでのみ機能し、Firefox + IEでは機能しません。最後の2つのブラウザーでトリガーしようとしても何も起こりません。

スクリプトとマークアップは、CMSからの継承によりiframe内に配置されますが、影響があるかどうかはわかりません。

最新のすべてのブラウザに最適化する方法についてのアイデアはありますか?

10
donpedroper

最新のすべてのブラウザに最適化する方法についてのアイデアはありますか?

はい、IE11、Firefox 47、およびChrome52。現時点ではMicrosoft Edgeには何もありません。

最初は、IEまたは他の2つのブラウザを使用しているかどうかを区別する必要があります。IE11では次を使用できます。

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

他の2つのブラウザの場合、コードはChromeで動作しますが、ドキュメントの本文に要素を追加しなかったため、Firefoxでは動作しません。

したがって、修正されたコードは次のとおりです。

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

このバージョンは、最新のすべてのブラウザーで動作します。

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();

私もサファリのバージョンを取得しようとしていましたが、うまくいきませんでした。それを調査し続け、その解決策を提供しようとします。

18
Dekel