Html 通过 HTML5 文件和 URL API 正确创建和提供 PDF Blob

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15467747/
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-29 06:36:36  来源:igfitidea点击:

Properly Create and Serve PDF Blob via HTML5 File and URL APIs

javascripthtmlfileblobs

提问by Eric H.

Ok, Let's say I have document data stored somewhere, let's arbitrarily take this pdf.

好吧,假设我在某处存储了文档数据,我们随意取这个 pdf

Issue #1. What I want to do is make an AJAX call to this URL (because I need to pass some authentication headers and it is cross domain). Then take the returned data, create a blob urlfor it, append an iFrame to the DOM, and direct the srcto the blob url.

问题#1。我想要做的是对该 URL 进行 AJAX 调用(因为我需要传递一些身份验证标头并且它是跨域的)。然后获取返回的数据,为其创建一个blob url,将一个 iFrame 附加到 DOM,并将 定向src到 blob url。

Currently my code looks like this:

目前我的代码是这样的:

$.ajax({
  url:'http://www.grida.no/climate/ipcc_tar/wg1/pdf/tar-01.pdf'
}).done(function(data){
   var file = new Blob([data], {type:'application/pdf'}),
       url = URL.createObjectURL(file),
       _iFrame = document.createElement('iframe');
      _iFrame.setAttribute('src', url);
      _iFrame.setAttribute('style', 'visibility:hidden;');
      $('#someDiv').append(_iFrame);
});

Unfortunately, I am getting a 'Failed to Render PDF' in the iFrame.

不幸的是,我在 iFrame 中收到“无法渲染 PDF”。

Issue #2. I'd like this to result in a file download prompt. Not sure how to guarantee this given that PDF's will naturally just display in the iFrame.

问题#2。我希望这会导致文件下载提示。不知道如何保证这一点,因为 PDF 自然只会显示在 iFrame 中。

回答by Ciantic

jQuery.ajax does not currently support blobs, see this bug report #7248which is closed as wontfix.

jQuery.ajax 目前不支持 blob,请参阅此错误报告 #7248,该报告已作为 wontfix 关闭。

However it's easy to do XHR for blobs without jQuery:

但是,在没有 jQuery 的情况下为 blob 执行 XHR 很容易:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.grida.no/climate/ipcc_tar/wg1/pdf/tar-01.pdf', true);
xhr.responseType = 'blob';

xhr.onload = function(e) {
  if (this.status == 200) {
    // Note: .response instead of .responseText
    var blob = new Blob([this.response], {type: 'application/pdf'}),
        url = URL.createObjectURL(blob),
        _iFrame = document.createElement('iframe');

    _iFrame.setAttribute('src', url);
    _iFrame.setAttribute('style', 'visibility:hidden;');
    $('#someDiv').append(_iFrame)        
  }
};

xhr.send();

Shamelessly copied from HTML5rocks.

无耻地从HTML5rocks复制而来。

If jQuery did support the Blob type, it could be as simple as:

如果 jQuery 确实支持 Blob 类型,那么它可以很简单:

$.ajax({
  url:'http://www.grida.no/climate/ipcc_tar/wg1/pdf/tar-01.pdf',
  dataType:'blob'
})...

回答by LordDraagon

I have used @Ciantic answer to adapt my answer. I have avoided using iframe obj and the user can download the file directly from the page.

我已经使用@Ciantic 的答案来调整我的答案。我避免使用 iframe obj,用户可以直接从页面下载文件。

var link = 'http://www.grida.no/climate/ipcc_tar/wg1/pdf/tar-01.pdf';
$("body").addClass("loading"); // adding the loading spinner class

var xhr = new XMLHttpRequest();
xhr.open('GET',link,true);
xhr.responseType = 'blob';

        xhr.onload = function(e){
                 if (this.status == 200) {
                    var a = document.createElement('a');
                    var url = window.URL.createObjectURL(new Blob([this.response], {type: 'application/pdf'}));
                    a.href = url;
                    a.download = 'report.pdf';
                    a.click();
                    window.URL.revokeObjectURL(url);
                    $('body').removeClass("loading"); //removing the loading spinner class
                  }else{
                      $('body').removeClass("loading") //removing the loading spinner class
                      console.log(this.status);
                      alert('Download failed...!  Please Try again!!!');
                  }
            };
            xhr.send();

回答by sanj singh

var src_url = your url here;
var contentDisposition = 'AlwaysInline';
var src_new = src_url.replace(/(ContentDisposition=).*?(&)/, '' + contentDisposition + '');

By doing this you will be able to view pdf instead of downloading it,

通过这样做,您将能够查看 pdf 而不是下载它,

Header ContentDisposition should be 'AlwaysInline' then only it displays your file instead of downloading it.

标题 ContentDisposition 应该是“AlwaysInline”,然后它只显示您的文件而不是下载它。