如何在内置PDF查看器的浏览器中针对base64 pdf自定义文件名

时间:2020-03-11 15:16:42

标签: javascript pdf base64 pdf.js pdfobject

我从这样的base64字符串中嵌入PDF:

var pdfData = 'data:application/pdf;filename=MY_CUSTOM_FILENAME.pdf;base64,' +
  'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
  'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
  'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
  'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
  'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
  'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
  'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
  'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
  'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
  'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
  'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
  'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
  'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G';

function loadPdf() {
  var pdf= document.querySelector('.pdf')

  var pobj = document.createElement('object')
  pobj.className= "pdf_object"
  pobj.setAttribute('data', pdfData)
  pobj.setAttribute('type', 'application/pdf')

  pdf.appendChild(pobj)
} 
.pdf_object {
  width: 100%;
  height: 700px;  
}
<div>
  <button onclick="loadPdf();">
    CLICK TO LOAD BELOW THE PDF
  </button>
</div>
<div class="pdf"></div>

这在Firefox和Chrome上均适用。

我的问题是我无法自定义pdf下载操作的文件名。请注意,我正在使用filename参数('data:application/pdf;filename=MY_CUSTOM_FILENAME.pdf;...),但是它被忽略了。

在Firefox上,我收到此警告(相关代码为here):

“ getPDFFileNameFromURL:出于性能原因,忽略“ data:” URL。”

并且pdf的文件名是默认的document.pdf

在Chrome上,我没有收到任何警告,但文件名坚持默认的download.pdf

那么,如何自定义文件名?有可能吗?

我尝试了这些方法,但均未成功:

  • 已选中PDFObject,这是一个基本上满足我在这篇文章中所做的工作的库(在编写此文件时发现了它!),但似乎不允许对文件名进行任何自定义。

  • 我试图在<iframe>上加载pdf,然后操纵其内容。但是我(至少在Firefox中)遇到了跨源错误

  • 似乎Mozilla的PDF查看器(PDF.js)还会检查Content-Disposition标头以猜测出pdf的文件名。可以以某种方式模拟HTTP请求(当我使用base64字符串时,总是在浏览器中本地)并使用它来加载pdf查看器吗?

我知道解决方案可以是直接使用PDF.js,但如果可能的话,我希望避免这种依赖关系(以及编码,因为实现起来并不那么简单)。最后,我只想自定义文件名!

谢谢!


编辑:下面的代码段在Chrome上不起作用(无法将'data:application / pdf; filename = MY_CUSTOM_FILENAME.pdf; base64,....'作为插件加载,因为该插件所在的框架加载是沙盒操作。),但如果您打开计划.html文件,则可以使用。


编辑2:我找到了一种解决方案,但它只能在Firefox上运行。

我们将base64字符串转换为Blob as explained here,将此Blob转换为Url并向此url添加一个filename参数(使用' #'as explained here)。

所以loadPdf()函数是这样的:

function loadPdf() {
  fetch(pdfData)
    .then(res => res.blob())
    .then(blob => {
      try {
        var blobUrl = URL.createObjectURL(blob)
        // This line makes Chrome crash, we have to remove it there
        // But it works on Firefox
        blobUrl+= '#filename=MY_CUSTOM_FILENAME.pdf'

        var pdf= document.querySelector('.pdf')
        var pobj = document.createElement('object')
        pobj.className= "pdf_object"
        pobj.setAttribute('data', blobUrl)
        pobj.setAttribute('type', 'application/pdf')

        pdf.appendChild(pobj)
      } catch(e) {
        console.error(e)
      }
  })
} 

从Firefox的Pdf查看器下载时,我们将成功看到MY_CUSTOM_FILENAME.pdf。

但是在Chrome上,我们将看到Blob网址的哈希值。并且:

从这个角度来看还有其他提示吗?

0 个答案:

没有答案