Set the default save as name for a an <embed> or <iframe> that uses a Blob

百般思念 提交于 2019-11-26 11:39:49

问题


I am generating a PDF in the browser using PDFKit (without node) and displaying it an iframe or an embed tag via the src attribute. The generated blob URL is some kind of UUID. So the overall page looks like:

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

The PDF appears fine, but when I click the Download link in Chrome, the default file name is the UUID. In FireFox, it is just \"document.pdf\".

If this were a server-generated PDF I would use Content-Disposition and/or manipulate the URL so the last part of it is the name I want, but that doesn\'t seem possible with a client-generated object.

Things I have tried:

  • Setting the PDF title via the metadata. This works but doesn\'t affect the filename.
  • Manipulating the embed tag title attribute. Doesn\'t seem to do anything.
  • Change the page title. Doesn\'t affect the file.
  • Try to append something to the data url. Just prevents the PDF from displaying.
  • Upload the PDF via POST, then download it via a page where I can control the URL. Could work, but seems crazy to generate a client-side PDF only to have to upload it to the server.

Is there any way around this so that I can control the default/suggested file name?


回答1:


I didn't find, yet, for chrome's default plugin.
I've got something that works for Firefox though, and which will default to download.pdf in chrome, for some odd reason...

By passing a dataURI in the form of

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

Firefox accepts FILE_NAME as the name of your file, but chrome doesn't...


A plnkr to show a better download.pdf in chrome, which doesn't like nested iframes...

And an snippet which will only work in 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>

But note that if it is really important to you, you could of course not rely on browser's own plugins, and use e.g Mozilla's PDF.js over which you'll get an extended control.




回答2:


Is there any way around this so that I can control the name?

No. You cannot control the name of a file stored at user local filesystem.

You can use <a> element with download attribute set to suggested file name. If user selects to download offered file user can change the file name at any time before or after downloading file.

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

At chrome, chromium browsers you can use requestFileSystem to store Blob, File or Directory at LocalFileSystem, which writes file to browser configuration directory, or other directories within user operating system. See

  • How to Write in file (user directory) using JavaScript?
  • jQuery File Upload Plugin: Is possible to preserve the structure of uploaded folders?
  • Where is Blob binary data stored?


来源:https://stackoverflow.com/questions/44061354/set-the-default-save-as-name-for-a-an-embed-or-iframe-that-uses-a-blob

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!