我从这样的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网址的哈希值。并且:
<iframe>
(而不是<object>
)加载内嵌pdf,Chrome也会使用<embed>
。因此,没有办法对其进行“破解”。从这个角度来看还有其他提示吗?