gpt4 book ai didi

javascript - 我可以设置在 Chrome 中显示的 PDF 对象的文件名吗?

转载 作者:数据小太阳 更新时间:2023-10-29 04:17:37 28 4
gpt4 key购买 nike

在我的 Vue 应用程序中,我收到一个 Blob 形式的 PDF,并希望使用浏览器的 PDF 查看器显示它。

我将它转换成一个文件,并生成一个对象 url:

const blobFile = new File([blob], `my-file-name.pdf`, { type: 'application/pdf' })
this.invoiceUrl = window.URL.createObjectURL(blobFile)

然后我通过将该 URL 设置为对象元素的 data 属性来显示它。

<object
:data="invoiceUrl"
type="application/pdf"
width="100%"
style="height: 100vh;">
</object>

然后浏览器使用 PDF 查看器显示 PDF。但是,在 Chrome 中,我提供的文件名(此处为 my-file-name.pdf)未被使用:我在 PDF 查看器的标题栏中看到一个散列,当我使用“右键单击”下载文件时-> 另存为...' 或查看器的控件,它使用 blob 的哈希值(cda675a6-10af-42f3-aa68-8795aa8c377d 或类似的)保存文件。

查看器和文件名在 Firefox 中如我所愿;只有 Chrome 没有使用文件名。

有什么方法可以使用 native Javascript(包括 ES6,但除 Vue 外没有第三方依赖项)在 Chrome 中设置 blob/object 元素的文件名?

[edit] 如果有帮助,响应具有以下相关 header :

Content-Type: application/pdf; charset=utf-8
Transfer-Encoding: chunked
Content-Disposition: attachment; filename*=utf-8''Invoice%2016246.pdf;
Content-Description: File Transfer
Content-Encoding: gzip

最佳答案

Chrome 的扩展似乎依赖于 URI 中设置的资源名称,即 protocol:/中的 file.ext/domain/path/file.ext.

因此,如果您的原始 URI 包含该文件名,最简单的方法可能是简单地将您的 data 设为您直接从中获取 pdf 的 URI,而不是按照 Blob 的方式。

现在,有些情况无法完成,对于这些情况,有一种复杂的方式,它可能在未来版本的 Chrome 中不起作用,而且可能在其他浏览器中也不起作用,需要设置Service Worker .

正如我们首先所说,Chrome 解析 URI 以搜索文件名,因此我们要做的是拥有一个 URI,该文件名指向我们的 blob://URI。

为此,我们可以使用缓存 API,使用我们的 URL 将我们的文件存储为请求,然后从 ServiceWorker 的缓存中检索该文件。

或者在代码中,

从主页

// register our ServiceWorker
navigator.serviceWorker.register('/sw.js')
.then(...
...

async function displayRenamedPDF(file, filename) {
// we use an hard-coded fake path
// to not interfere with legit requests
const reg_path = "/name-forcer/";
const url = reg_path + filename;
// store our File in the Cache
const store = await caches.open( "name-forcer" );
await store.put( url, new Response( file ) );

const frame = document.createElement( "iframe" );
frame.width = 400
frame.height = 500;
document.body.append( frame );
// makes the request to the File we just cached
frame.src = url;
// not needed anymore
frame.onload = (evt) => store.delete( url );
}

在 ServiceWorker sw.js

self.addEventListener('fetch', (event) => {
event.respondWith( (async () => {
const store = await caches.open("name-forcer");
const req = event.request;
const cached = await store.match( req );
return cached || fetch( req );
})() );
});

Live example ( source )

编辑:这实际上在 Chrome 中不起作用...

虽然它确实在对话框中正确设置了文件名,但在将文件保存到磁盘时他们似乎无法检索文件...
他们似乎没有执行网络请求(因此我们的软件没有捕捉到任何东西),我现在真的不知道去哪里看。
这仍然可能是 future 在这方面工作的良好基础。


另一个解决方案是运行您自己的 pdf 查看器,我没有花时间自己检查。

Mozilla 已经制作了基于 js 的插件 pdf.js可用,所以从那里我们应该能够设置文件名(即使我再一次没有挖掘那里)。


最后要注意的是,Firefox 能够使用 blobURI 指向的 File 对象的 name 属性。所以即使这不是 OP 要求的,在 FF 中它所需要的只是

const file = new File([blob], filename);
const url = URL.createObjectURL(file);
object.data = url;

关于javascript - 我可以设置在 Chrome 中显示的 PDF 对象的文件名吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53548182/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com