Javascript 使用jquery ajax下载pdf文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34586671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:36:05  来源:igfitidea点击:

Download pdf file using jquery ajax

javascriptjqueryajaxpdf

提问by azhar

I want to download a pdf file for jquery ajax response. Ajax response contains pdf file data. I tried this solution. My code is given below but I always get a blank pdf.

我想下载 jquery ajax 响应的 pdf 文件。Ajax 响应包含 pdf 文件数据。我试过这个解决方案。我的代码在下面给出,但我总是得到一个空白的 pdf。

$(document).on('click', '.download-ss-btn', function () {

    $.ajax({
        type: "POST",
        url: 'http://127.0.0.1:8080/utils/json/pdfGen',
        data: {
            data: JSON.stringify(jsonData)
        }

    }).done(function (data) {
        var blob = new Blob([data]);
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = "Sample.pdf";
        link.click();
    });


});

回答by Hisham

jQuery has some issues loading binary data using AJAX requests, as it does not yet implement some HTML5 XHR v2 capabilities, see this enhancement requestand this discussion

jQuery 在使用 AJAX 请求加载二进制数据时存在一些问题,因为它还没有实现一些 HTML5 XHR v2 功能,请参阅此增强请求和此讨论

Given that, you have one of two solutions:

鉴于此,您有以下两种解决方案之一:

First solution, abandon JQuery and use XMLHTTPRequest

第一种解决方案,放弃JQuery,使用XMLHTTPRequest

Go with the native HTMLHTTPRequest, here is the code to do what you need

使用本机 HTMLHTTPRequest,这是执行您需要的代码

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

  req.onload = function (event) {
    var blob = req.response;
    console.log(blob.size);
    var link=document.createElement('a');
    link.href=window.URL.createObjectURL(blob);
    link.download="Dossier_" + new Date() + ".pdf";
    link.click();
  };

  req.send();

Second solution, use the jquery-ajax-native plugin

第二种解决方案,使用jquery-ajax-native插件

The plugin can be found hereand can be used to the XHR V2 capabilities missing in JQuery, here is a sample code how to use it

该插件可以在这里找到并且可以用于 JQuery 中缺少的 XHR V2 功能,这里是如何使用它的示例代码

$.ajax({
  dataType: 'native',
  url: "/file.pdf",
  xhrFields: {
    responseType: 'blob'
  },
  success: function(blob){
    console.log(blob.size);
      var link=document.createElement('a');
      link.href=window.URL.createObjectURL(blob);
      link.download="Dossier_" + new Date() + ".pdf";
      link.click();
  }
});

回答by anonymous

I am newbie and most of the code is from google search. I got my pdf download working with the code below (trial and error play). Thank you for code tips (xhrFields) above.

我是新手,大部分代码来自谷歌搜索。我使用下面的代码下载了我的 pdf 文件(试错游戏)。感谢您提供上面的代码提示 (xhrFields)。

$.ajax({
            cache: false,
            type: 'POST',
            url: 'yourURL',
            contentType: false,
            processData: false,
            data: yourdata,
             //xhrFields is what did the trick to read the blob to pdf
            xhrFields: {
                responseType: 'blob'
            },
            success: function (response, status, xhr) {

                var filename = "";                   
                var disposition = xhr.getResponseHeader('Content-Disposition');

                 if (disposition) {
                    var filenameRegex = /filename[^;=\n]*=((['"]).*?|[^;\n]*)/;
                    var matches = filenameRegex.exec(disposition);
                    if (matches !== null && matches[1]) filename = matches[1].replace(/['"]/g, '');
                } 
                var linkelem = document.createElement('a');
                try {
                                           var blob = new Blob([response], { type: 'application/octet-stream' });                        

                    if (typeof window.navigator.msSaveBlob !== 'undefined') {
                        //   IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
                        window.navigator.msSaveBlob(blob, filename);
                    } else {
                        var URL = window.URL || window.webkitURL;
                        var downloadUrl = URL.createObjectURL(blob);

                        if (filename) { 
                            // use HTML5 a[download] attribute to specify filename
                            var a = document.createElement("a");

                            // safari doesn't support this yet
                            if (typeof a.download === 'undefined') {
                                window.location = downloadUrl;
                            } else {
                                a.href = downloadUrl;
                                a.download = filename;
                                document.body.appendChild(a);
                                a.target = "_blank";
                                a.click();
                            }
                        } else {
                            window.location = downloadUrl;
                        }
                    }   

                } catch (ex) {
                    console.log(ex);
                } 
            }
        });

回答by Luca Ziegler

You can do this with html5 very easily:

你可以很容易地用 html5 做到这一点:

var link = document.createElement('a');
link.href = "/WWW/test.pdf";
link.download = "file_" + new Date() + ".pdf";
link.click();

回答by Alain Cruz

For those looking a more modern approach, you can use the fetch API. The following example shows how to download a PDFfile. It is easily done with the following code.

对于那些寻求更现代方法的人,您可以使用fetch API. 以下示例显示了如何下载PDF文件。使用以下代码可以轻松完成。

fetch(url, {
    body: JSON.stringify(data),
    method: 'POST',
    headers: {
        'Content-Type': 'application/json; charset=utf-8'
    },
})
.then(response => response.blob())
.then(response => {
    const blob = new Blob([response], {type: 'application/pdf'});
    const downloadUrl = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = downloadUrl;
    a.download = "file.pdf";
    document.body.appendChild(a);
    a.click();
})

I believe this approach to be much easier to understand than other XMLHttpRequestsolutions. Also, it has a similar syntax to the jQueryapproach, without the need to add any additional libraries.

我相信这种方法比其他XMLHttpRequest解决方案更容易理解。此外,它具有与该jQuery方法类似的语法,无需添加任何额外的库。

Of course, I would advise checking to which browser you are developing, since this new approach won't work on IE. You can find the full browser compatibility list on the following [link][1].

当然,我建议检查您正在开发的浏览器,因为这种新方法不适用于 IE。您可以在以下 [链接][1] 中找到完整的浏览器兼容性列表。

Important: In this example I am sending a JSON request to a server listening on the given url. This urlmust be set, on my example I am assuming you know this part. Also, consider the headers needed for your request to work. Since I am sending a JSON, I must add the Content-Typeheader and set it to application/json; charset=utf-8, as to let the server know the type of request it will receive.

重要提示:在本例中,我将一个 JSON 请求发送到侦听给定url. 这url必须设置,在我的例子中,我假设你知道这部分。此外,请考虑您的请求工作所需的标头。由于我发送的是 JSON,因此我必须添加Content-Type标头并将其设置为application/json; charset=utf-8,以便让服务器知道它将接收的请求类型。