【问题标题】:Download pdf file using jquery ajax使用 jquery ajax 下载 pdf 文件
【发布时间】:2016-04-07 19:13:50
【问题描述】:

我想下载一个用于 jquery ajax 响应的 pdf 文件。 Ajax 响应包含 pdf 文件数据。我试过这个solution。我的代码在下面给出,但我总是得到一个空白的 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();
    });


});

【问题讨论】:

  • 尝试用XMLHttpRequest 替换jQuery.ajax() 参见stackoverflow.com/questions/12876000/…
  • 为什么需要为此使用 AJAX?没有它,下载文件会更容易、更可靠。
  • 您不能使用json 响应制作pdf。它应该是HTML 响应,并且它不适用于所有浏览器。在给定的前。它返回 Url 表示 HTML 响应。
  • 这里我使用网络服务来获取 json 数据的格式化 pdf 文件。响应pdf文件数据以%PDF-1.4开头
  • 您必须在success 然后.done 以及您正在测试的browser 版本中编写代码。 ` Blob([data])` 在某些浏览器中不起作用。

标签: javascript jquery ajax pdf


【解决方案1】:

jQuery 在使用 AJAX 请求加载二进制数据时存在一些问题,因为它尚未实现一些 HTML5 XHR v2 功能,请参阅此enhancement request 和此discussion

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

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

使用原生 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();

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

插件可以在here找到,可以用于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();
  }
});

【讨论】:

  • 要使其在 Firefox 中工作,您必须添加 'document.body.appendChild(link);'在点击链接之前:)
  • 工作得很好,但我发现你需要 window.navigator.msSaveBlob(blob, filename);如@anonymous 所示,使其在 IE11 中工作。
  • 非常感谢!
  • 这正是我所需要的。 xhrFields: { responseType: 'blob' },
  • InvalidStateError: 无法从 'XMLHttpRequest' 读取 'responseText' 属性:只有当对象的 'responseType' 是 '' 或 'text' (是 'blob')时才能访问该值。跨度>
【解决方案2】:

我是新手,大部分代码来自谷歌搜索。我的 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]*=((['"]).*?\2|[^;\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);
                } 
            }
        });

【讨论】:

  • 你是我的英雄。谢谢你:)
  • 5 小时和大约 30 个其他属性添加到 .ajax({})...并且 xhrFields 修复了它。非常感谢!
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    对于那些寻求更现代方法的人,您可以使用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();
    })
    

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

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

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

    【讨论】:

    • 数据未定义!但是当我删除第 2 行时它可以工作。
    • 那是因为你需要定义它,除非你的请求不需要正文。
    猜你喜欢
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    相关资源
    最近更新 更多