从 arraybuffer 显示 pdf

IT技术 javascript php jquery laravel dompdf
2021-01-29 01:52:36

我正在从此代码返回来自 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文件。

3个回答

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

还要注意,铬,铬有显示问题.pdf在任<object><embed>元素,请参阅使用对象嵌入标记与斑点URL显示PDF嵌入使用PDFObject的Blob<iframe>元素替换<object>元素。

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

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

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

这很好,但请注意,它不会让您命名 PDF 文件。
2021-03-16 01:52:36
@mlissner 下载文件与当前问题无关。 元素的download属性值<a>仅提供文件名的建议供下载文件。Save File下载文件后,可以在提示时或在本地文件系统中重命名该文件。有关下载文件的问题和答案,请参阅如何使用 javascript 从 Web 服务返回的二进制字符串构建 PDF文件。
2021-03-16 01:52:36
但是,如果您为 src 属性创建带有 blob URLobjectiframe,如果您尝试下载它,它的文件名就会混乱。您链接到的问答是一个很好的解决方案(谢谢!),但是如果您选择下载文件,上面的这个答案确实会导致文件名称出现问题。不是吗?
2021-04-04 01:52:36
当你去下载它时,你会得到 blob URL,而不是文件的名称。
2021-04-05 01:52:36
@mlissner“命名PDF文件”是什么意思?
2021-04-07 01:52:36

我很喜欢guest271314的答案,尤其是使用fetch的第二个版本,但我想添加一个不使用polyfill或实验技术的解决方案,如fetch.

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

  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

从我的测试中,响应是响应而不是 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 输出的响应做一些事情......(使用 javascript 下载时 PDF 是空白的)。这将起作用:

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();
@AndrewMonks默认jQuery.ajax()没有responseType设置。
2021-03-17 01:52:36
@AndrewMonks “从我的测试中,响应是响应而不是 response.data,所以以下应该有效”你能在 stacksnippets、jsfiddle jsfiddle.net或 plnkr plnkr.co 上分享测试吗?
2021-03-18 01:52:36
不幸的是,您无法将 pdf 文件上传到片段站点,并且 COR 会阻止对其他站点 PDF 文件的请求。尽管请参阅stackoverflow.com/questions/34436133/...我再次检查并得到一个空白输出。尝试使用原始 XMLHttpRequest 而不是 jquery,它会起作用。
2021-03-30 01:52:36
更改response.dataresponse我得到完全空白的 pdf 后。没有输出。我认为我们即将解决这个问题,可能需要在任何地方responseTypeContent-type任何地方进行更改
2021-04-01 01:52:36