3

I have a blob url and a button on my site. The user can click on that button and the blob opens in a new tab.

<a class="downloadlink" id="downloadlink" target="_blank" href="[[_blobUrl]]"></a>

This works.

If the user has the setting for the file type behind this blob (e.g. pdf) to save the file instead of previewing it in the browser, the file gets downloaded of course. But firefox creates a random filename of the format

[a-zA-Z0-9]{8}\.pdf

Chrome uses the blob uuid and appends pdf.

How can I control the filename AND respect the users preferences?

When I add the download attribute the file gets always downloaded, also when the user has the setting "Preview" for the specified file type. I want the behavior the user prefers (preview or download) but still control the filename in case the user prefers downloading the file.

Update for firefox: I got a solution for firefox but it is not working in chrome. Instead of

this._blobUrl = URL.createObjectURL(blob);

I do

let file = new File([blob], this.downloadname, {type: 'application/pdf'});
this._blobUrl = URL.createObjectURL(file);
Christian
  • 3,503
  • 1
  • 26
  • 47
  • This question is clearly not a duplicate of the above mentioned. I don't need to explain that. The mod should explain why he thinks this is a dup. – Christian Apr 26 '19 at 18:12
  • @Kaiido To your second suggestion: I did not mention iframe or embed. The file is not (!) displayed. It is not a default filename for a "Save as" action. It is just a click on a link and either the file gets downloaded or not, depending on the user preferences. Regarding your first suggestion: Again, I do not display anything, and there is no "Save As" action involved. Despite that, the solution named there could work. I have to try. Just because the solutions are the same, doesn't mean the problems are the same. None of your answers name user preferences. So I don't think it's a dupe. – Christian Apr 27 '19 at 13:14
  • @Kaiido Actually I don't care about the filename in the case the user opens the file in a new tab. Actually your mark also suggests I should never have asked the question, but I don't think I did something wrong here. I asked for help in the case of a download, both questions are about displaying. So it is nothing I found when I was searching for it. Again, the same solution does not imply the same question. – Christian Apr 28 '19 at 12:41
  • I think you have a misunderstanding of what closing as duplicate means. No, you didn't made **anything** wrong, and there is absolutely nothing wrong in the fact it got closed. Closing as duplicate is a mean to redirect users with the same question to a single sign-post, where all the answers can be gathered, so that everyone can find them easily, instead of having a lot of posts everywhere, with no means to compare them. If you check [my own history as a question asker](https://stackoverflow.com/users/3702797/kaiido?tab=questions) you'll see that 1/3 of my questions got closed as duplicate. – Kaiido Apr 28 '19 at 12:51
  • @Kaiido Partly you are right. But for instance if I could know what the user prefers I can set the download attribute in the case the user prefers downloading instead of previewing. And then a solution to my problem could differ. But If you think duplicate so it be. – Christian Apr 28 '19 at 20:07
  • seems I was blinded by what I though I know... Actually you are right, an other solution could exist to your question. – Kaiido May 10 '19 at 10:55
  • Thx for understanding. – Christian May 11 '19 at 18:10

2 Answers2

1

Chrome does expose this preference through the navigator.plugins dictionary. If this object contains a PDF Reader, then you know the user wants to see it displayed in their browser.

const opensInBrowser = [...navigator.plugins].some(plug => [...plug].some(mime => mime.type === 'application/pdf'))
console.log(opensInBrowser);

But this does only work for Chrome. Firefox doesn't expose this information here (IIRC they don't technically use a Plugin to display the pdf). So this means that we can't use only this; Firefox will always be marked as not opening in browser, while it may very well be.

So I think the only way is still a very long one... exposed in details here..

Using a Service Worker, we can fake a request to a named file, that Chrome will use to set the name, both of the downloaded file and of the pdf read by the plugin.

That is until they follow Firefox in forwarding correctly File objects names through the Blob URIs that point to them.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • I have a solution for Firefox. This is one for Chrome. I have no problem with writing browser specific solutions, where browsers differ in behavior. I will try this asap and mark your answer as correct if it works. – Christian May 11 '19 at 18:14
  • This works perfectly for chrome. Depending on `opensInBrowser` in the case of chrome browser I set the download attribute. – Christian May 13 '19 at 12:27
0

Simpliest solution (that should also work with IE10) is to create an a element, attach it to body, set it's name, let user download it and remove after, something like this:

function save(){
  const file = new File(['this is where BLOB should go'], {type: 'application/pdf'}); // edit this line to have access to source blob
  const link = document.createElement('a');

  link.href = URL.createObjectURL(file);
  link.download = 'this is the name.pdf';

  document.body.appendChild(link);
  link.click();

  document.body.removeChild(link);
}

window.save = save;

and for HTML:

<a class="downloadlink" id="downloadlink" target="_blank" onclick='save()'>here is your link</a>

working example can be found here

take notice of:

  • you should edit the onclick function to pass the blob you're expecting to be as an output of the file
  • in example i created a pdf only, however you can extend this functionality pretty easily to any kind of document you need (and is recognizable by given browser)
Tooschee
  • 681
  • 6
  • 11
  • As I said already in my question: When I add the download attribute the file gets always downloaded, also when the user has the setting "Preview" for the specified file type. The question is about setting a name AND respecting the user preferences. – Christian Apr 25 '19 at 03:28