【问题标题】:Displaying pdf from arraybuffer从arraybuffer显示pdf
【发布时间】:2017-06-25 16:26:26
【问题描述】:

我正在从此代码中返回来自 laravel dompdf 的流数据

 $pdf = \App::make('dompdf.wrapper');
 $pdf->loadHTML("<div>This is test</div>");
 return $pdf->stream();

这是我的 JS ajax 代码

    $.ajax({
        type:"GET",
        url: "/display",
        responseType: 'arraybuffer'
    }).done(function( response ) {
        var blob = new Blob([response.data], {type: 'application/pdf'});
        var pdfurl = window.URL.createObjectURL(blob)+"#view=FitW";
        $("#pdfviewer").attr("data",pdfurl);
    });

这是在 ajax 之后显示 pdf 的 HTML

<object id="pdfviewer" data="/files/sample.pdf" type="application/pdf" style="width:100%;height:500px;"></object>

我遇到了错误

加载 PDF 文档失败

请帮助解决这个问题。如何显示pdf文件。

【问题讨论】:

    标签: javascript php jquery laravel dompdf


    【解决方案1】:

    jQuery.ajax() 默认没有responseType 设置。您可以使用 polyfill,例如实现二进制数据传输的 jquery-ajax-blob-arraybuffer.js,或使用 fetch()

    另请注意,chrome、chromium 在&lt;object&gt;&lt;embed&gt; 元素上显示.pdf 时存在问题,请参阅Displaying PDF using object embed tag with blob URLEmbed a Blob using PDFObject。使用&lt;iframe&gt; 元素替换&lt;object&gt; 元素。

    $(function() {
    
      var pdfsrc = "/display";
    
      var jQueryAjaxBlobArrayBuffer = "https://gist.githubusercontent.com/SaneMethod/" 
                             + "7548768/raw/ae22b1fa2e6f56ae6c87ad0d7fbae8fd511e781f/" 
                             + "jquery-ajax-blob-arraybuffer.js";
    
      var script = $("<script>");
    
      $.get(jQueryAjaxBlobArrayBuffer)
      .then(function(data) {
        script.text(data).appendTo("body")
      }, function(err) {
        console.log(err);
      })
      .then(function() {
        $.ajax({
          url: pdfsrc,
          dataType: "arraybuffer"
        })
        .then(function(data) {
          // do stuff with `data`
          console.log(data, data instanceof ArrayBuffer);
          $("#pdfviewer").attr("src", URL.createObjectURL(new Blob([data], {
                type: "application/pdf"
              })))
         }, function(err) {
              console.log(err);
         });
    
      });
    });
    

    使用fetch().arrayBuffer()

      var pdfsrc = "/display";
    
      fetch(pdfsrc)
      .then(function(response) {
        return response.arrayBuffer()
      })
      .then(function(data) {
        // do stuff with `data`
        console.log(data, data instanceof ArrayBuffer);
        $("#pdfviewer").attr("src", URL.createObjectURL(new Blob([data], {
            type: "application/pdf"
        })))
      }, function(err) {
          console.log(err);
      });
    

    plnkrhttp://plnkr.co/edit/9R5WcsMSWQaTbgNdY3RJ?p=preview

    版本 1 jquery-ajax-blob-arraybuffer.js, jQuery.ajax();版本 2 fetch(), .arrayBuffer()

    【讨论】:

    • 这很好,但请注意,它不会让您为 PDF 文件命名。
    • @mlissner “命名 PDF 文件”是什么意思?
    • 当你去下载它时,你会得到 blob URL,而不是文件名。
    • @mlissner 下载文件与当前问题无关。 &lt;a&gt; 元素中的download 属性值仅提供对提供下载文件的文件名的建议。该文件可以在Save File 提示符或下载文件后在本地文件系统重命名。有关下载文件的问题和答案,请参阅 How to build PDF file from binary string returned from a web-service using javascript
    • 但是,如果你创建一个objectiframe 并为 src 属性创建一个 blob URL,如果你尝试下载它,它的文件名就会混乱。您链接到的问答是一个很好的解决方案(谢谢!),但是如果您选择下载它,上面的这个答案确实会产生文件名称问题。不是吗?
    【解决方案2】:

    我非常喜欢guest271314 的回答,尤其是第二个使用fetch 的版本,但我想添加一个不使用polyfill 或fetch 之类的实验技术的解决方案。

    此解决方案使用本机 XMLHttpRequest API 创建请求。这允许我们将responseType 更改为arrayBuffer

      var xhr = new XMLHttpRequest();
      var pdfsrc = "https://upload.wikimedia.org/wikipedia/en/6/62/Definition_of_management.pdf";
      xhr.open('GET', pdfsrc, true);
      xhr.responseType = "arraybuffer";
    
      xhr.addEventListener("load", function (evt) {
        var data = evt.target.response;
        if (this.status === 200) {
          $("#pdfviewer").attr("src", URL.createObjectURL(new Blob([data], {
            type: "application/pdf"
          })));
        }
      }, false);
    
      xhr.send();
    

    我派生了 guest271314s plnkr 来展示这个方法的实际效果: http://plnkr.co/edit/7tfBYQQdnih9cW98HSXX?p=preview

    【讨论】:

      【解决方案3】:

      根据我的测试,响应是响应而不是 response.data,因此以下应该有效:

        $.ajax({
              type:"GET",
              url: "/display",
              responseType: 'arraybuffer'
          }).done(function( response ) {
              var blob = new Blob([response], {type: 'application/pdf'});
              var pdfurl = window.URL.createObjectURL(blob)+"#view=FitW";
              $("#pdfviewer").attr("data",pdfurl);
          });
      

      虽然看起来 JQuery 正在对导致空白 PDF 输出的响应做一些事情......(PDF is blank when downloading using javascript)。这将起作用:

      var xhr = new XMLHttpRequest();
      xhr.open('GET', 'test.pdf', true);
      xhr.responseType = 'arraybuffer';
      xhr.onload = function(e) {
         if (this.status == 200) {
              var blob=new Blob([this.response], {type:"application/pdf"});
              var pdfurl = window.URL.createObjectURL(blob)+"#view=FitW";
              $("#pdfviewer").attr("data",pdfurl);
         }
      };
      xhr.send();
      

      【讨论】:

      • 在将response.data 更改为response 之后,我得到了完全空白的pdf。没有输出。我想我们快要解决这个问题了,可能需要在 responseTypeContent-type 任何地方进行更改。
      • @AndrewMonks “从我的测试来看,响应是响应而不是 response.data,所以以下应该可以工作” 你能在 stacksn-ps 上分享测试吗,jsfiddle @987654322 @, 或 plnkr plnkr.co ?
      • 不幸的是,您不能将 pdf 文件上传到 sn-p 站点,并且 COR 会阻止对其他站点 PDF 文件的请求。虽然看到stackoverflow.com/questions/34436133/… 我再次检查并得到一个空白输出。尝试使用原始 XMLHttpRequest 而不是 jquery,它会起作用。
      • @AndrewMonks jQuery.ajax() 默认没有responseType 设置。
      猜你喜欢
      • 2021-03-02
      • 1970-01-01
      • 2022-11-28
      • 1970-01-01
      • 2020-01-19
      • 2011-07-24
      • 2020-10-08
      • 2011-01-14
      • 1970-01-01
      相关资源
      最近更新 更多