为使用 Blob 的 <embed> 或 <iframe> 设置默认另存为名称

IT技术 javascript html pdf node-pdfkit
2021-02-27 14:58:16

我正在使用 PDFKit(无节点)在浏览器中生成 PDF,并通过 src 属性将其显示为 iframe 或嵌入标签。生成的 blob URL 是某种 UUID。所以整个页面看起来像:

<embed src="blob:http://localhost/eeaabb..."/>

PDF 看起来不错,但是当我在 Chrome 中单击下载链接时,默认文件名是 UUID。在 FireFox 中,它只是“document.pdf”。

如果这是服务器生成的 PDF,我将使用 Content-Disposition 和/或操作 URL,因此它的最后一部分是我想要的名称,但这对于客户端生成的对象似乎是不可能的。

我尝试过的事情:

  • 通过元数据设置 PDF 标题。这有效但不影响文件名。
  • 操作嵌入标签标题属性。好像什么都没做
  • 更改页面标题。不影响文件。
  • 尝试在数据 url 中附加一些内容。只是阻止显示 PDF。
  • 通过 POST 上传 PDF,然后通过我可以控制 URL 的页面下载它。可以工作,但生成客户端 PDF 只需要将其上传到服务器似乎很疯狂。

有什么办法可以解决这个问题,以便我可以控制默认/建议的文件名?

2个回答


注意:
此答案已过时。
以下描述的行为自发布以来确实发生了变化,并且将来可能仍会发生变化。
由于此问题已在其他地方提出,并且得到了更好的答复,因此我邀请您阅读以下内容:我可以设置 Chrome 中显示的 PDF 对象的文件名吗?



我还没有找到 chrome 的默认插件。
不过,我有一些适用于 Firefox 的东西,但download.pdf出于某种奇怪的原因,它会默认为chrome...

通过以以下形式传递 dataURI

'data:application/pdf;headers=filename%3D' + FILE_NAME + ';base64,...'

Firefox 接受 FILE_NAME 作为您的文件名,但 chrome 不接受...


一个plnkr展现出更好的download.pdf铬,其中不喜欢在嵌套的iframe ...

还有一个仅适用于 FF 的片段:

const FILE_NAME = 'myCoolFileName.pdf';
const file_header = ';headers=filename%3D';

fetch('https://dl.dropboxusercontent.com/s/rtktu1zwurgd43q/simplePDF.pdf?dl=0').then(r => r.blob())
.then(blob=>{
  const f = new FileReader();
  f.onload = () => myPdfViewer.src = f.result.replace(';', file_header + encodeURIComponent(FILE_NAME) + ';');
  f.readAsDataURL(blob);
  });
<iframe id="myPdfViewer" width="500" height="500"></iframe>

但请注意,如果它对您来说真的很重要,您当然不能依赖浏览器自己的插件,而使用例如Mozilla 的 PDF.js,您将获得扩展控制。

在 Firefox 中,它将作为“document.pdf”在 Chrome 中作为“download.pdf”下载
2021-04-28 14:58:16
建议的文件名仅在data URI导航到单独的浏览器选项卡并单击下载图标时出现在提示处,而不是在<embed><iframe>元素内。目前尚不清楚原始问题中的“下载链接”指的是什么。
2021-04-29 14:58:16
@guest271314 我添加了一个指向chromeplnkr的链接你必须点击的是这个i.stack.imgur.com/jyf0k.png
2021-05-06 14:58:16
出现width,height设置<iframe>确定是否显示下载图标plnkr.co/edit/tvVEtIpKxK1YUStGNl3Q?p=preview
2021-05-06 14:58:16
试试 FF,不幸的是,它甚至无法加载到 chrome 上,可能是因为 iframe 的限制。显然确实出现在我的本地主机上...
2021-05-10 14:58:16

有什么办法可以解决这个问题,以便我可以控制名称?

不可以。您无法控制存储在用户本地文件系统中的文件的名称。

您可以使用属性设置为建议文件名的<a>元素download如果用户选择下载提供的文件,用户可以在下载文件之前或之后随时更改文件名。

window.onload = () => {
  let blob = new Blob(["file"], {
    type: "text/plain"
  });
  let url = URL.createObjectURL(blob);
  let a = document.createElement("a");
  a.href = url;
  a.download = "file.txt";
  document.body.appendChild(a);
  console.log(url);
  a.click();
}

在镀铬,铬的浏览器可以使用requestFileSystem存储BlobFileDirectoryLocalFileSystem哪个用户操作系统中写入文件浏览器配置目录或其他目录。

“当我在 Chrome 中单击下载链接时”这是来自 pdf 查看器插件的下载链接。
2021-04-21 14:58:16
我认为它实际上并没有回答实际问题(即使从我的调查中得出相同的“不”答案也适用):OP 正试图控制内置 chrome 的 pdf-viewer 插件,它确实公开了一个“下载”按钮。
2021-05-06 14:58:16
@Kaiido 然后 OP 应该检查插件代码,进行必要的调整,或者编写自己的.pdf查看器插件。如果 OP 尝试在 pdf 查看器插件之外提供文件以供下载,请使用<a>具有download属性集的元素来建议所提供文件的文件名。OP 也可以尝试用data URIfor代替Blob URL这两种方法都不能“控制”用户文件系统中下载文件的文件名。
2021-05-06 14:58:16
@Kaiido OP.pdf在问题中没有提到插件?答案与在用户文件系统上下载文件和“控制”下载文件的名称相同。
2021-05-11 14:58:16