90

I've experienced some unexpected behavior of Chrome since the newest version: While in Firefox this Code is working Perfectly fine:

<a 
  id="playlist"
  class="button"
  download="Name.xspf" 
  href="data:application/octet-stream;base64,PD94ANDSOON" 
  style="display: inline;">
    Download Me
</a>

It isn't working in Chrome (Simply downloading a file named "Download"), but has worked pretty fine before. What do I have to change that it is working again?

Philippe Fanaro
  • 6,148
  • 6
  • 38
  • 76
Buffer Overflow
  • 946
  • 1
  • 8
  • 9
  • This also happens when you are opening your website without a server (like a localhost), installing and using Ritiwick Dey's Live Server extension in VS code solves the problem, you can also use any other server like apache or xampp, but it would be easier and faster to install VS Code's Live Server extension. – Rishav Jha Jun 28 '21 at 01:11

12 Answers12

72

After some research I have finally found your problem.

<a>'s download attribute:

If the HTTP header Content-Disposition: is present and gives a different filename than this attribute, the HTTP header has priority over this attribute.

If this attribute is present and Content-Disposition: is set to inline, Firefox gives priority to Content-Disposition, like for the filename case, while Chrome gives priority to the download attribute.

Source

HTTP-Header Content-Disposition

Philippe Fanaro
  • 6,148
  • 6
  • 38
  • 76
Emanuel Vintilă
  • 1,911
  • 4
  • 25
  • 35
  • 7
    My Server doesn't seem to send "Content-Disposition" and as described by you Firefox wouldn't donwload the File correctly, but my problem is reversed: Chrome isn't accepting the download attr, while Firefox does. Even if i just create a simple HTML file with only this as its content (and opened as a file-url) it won't work in Chrome but in Firefox. It also worked before I updated Chrome (Version 35.0.1916.114 m) – Buffer Overflow May 26 '14 at 17:08
  • It doesn't work in Chrome for me as well... I surfed some sites with a "Try it" page, but neither their examples didn't work, nor some JSFIDDLE I tried to make. The only one which worked was [this one](http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_a_download2) on W3Schools. – Emanuel Vintilă May 26 '14 at 18:41
  • 4
    It seems to be a bug in Chrome as of version 35: https://code.google.com/p/chromium/issues/detail?id=373182 – Buffer Overflow May 28 '14 at 12:02
  • Thanks for sharing, hopefully they'll fix it ASAP. – Emanuel Vintilă May 28 '14 at 16:01
  • I'm getting chrome ignoring the "download" attribute... such a pita really – MrMesees Feb 07 '17 at 15:45
  • 25
    @MrMesees If I remember correctly, browsers no longer honor the download attribute, unless the href points to a resource that is on the same origin. Also see the answer below – Emanuel Vintilă Feb 07 '17 at 19:27
  • This doesn't actually provide a solution – Ryan Walker May 20 '19 at 17:26
  • @RyanWalker The solution is to use the Content-Disposition HTTP Header. – Emanuel Vintilă May 20 '19 at 17:36
  • 8
    That works if you have control over the server, but isn't a solution for the Front-End. I still can't figure out how to do it in html when the server doesn't have the `Content-Disposition` header. – Ryan Walker May 20 '19 at 21:19
  • 1
    if I store files in aws s3, and want to download files using presigned URL - this solution wont works for me, right? I am familiar only with front-end part - that is why asking – Andryxa Piddubnjak Oct 06 '20 at 08:10
71

Reading the comments, I had the same issue as @buffer-overflow and found this in the issue:

I'm guessing that the web page and the download are on different origins. We no longer honor the download attribute suggested filename for cross origin requests. Clicking on the link still initiates a download. But the the filename is only derived from factors solely dependent on the server (e.g. Content-Disposition header in the response and the URL).

So no chance I could make it work ... :(

cachius
  • 1,743
  • 1
  • 8
  • 21
Augustin Riedinger
  • 20,909
  • 29
  • 133
  • 206
  • 7
    There is nothing about that restriction in the W3C recommendation of the HTML5 and HTML 5.1, but you can find at the Mozilla reference. "This attribute only works for same-origin URLs." - from https://developer.mozilla.org/en/docs/Web/HTML/Element/a#Attributes – Quidn Apr 02 '17 at 19:43
  • I have the same problem with chrome version 57 despite no `Content-Disposition` header is present. The only solution I found was to make the server add the `Content-Disposition` header and specify the filename there. – Readren Apr 12 '17 at 07:59
  • 3
    i am seeing totally different behavior... it's not even *trying* to download, instead it's acting as if the download attribute wasn't there, and is replacing the page with the new image! – Michael Mar 31 '20 at 02:27
14

I had this problem with wordpress, the problem is that wordpress generates the full path of the file, and in the a tag you have to remove the full domain name and add a relative path

Example, instead of:

<a href="http://mywordpresssite.com/wp-content/uploads/file.mp4" download="file.mp4" >

You have to do this:

<a href="/wp-content/uploads/file.mp4" download="file.mp4">

This will make it work

Dharman
  • 30,962
  • 25
  • 85
  • 135
oware
  • 626
  • 9
  • 19
4

This is the current behaviour in Chrome as of 16 Aug, 2021

If you are calling an api like this: http://localhost:9000/api/v1/service/email/attachment/dummy.pdf

Chrome will try to parse the last value of the path param and ignore any value passed to attachment attribute of a link if Content-Disposition is not set or is set to inline from the server, in which case the pdf file will have the name dummy.pdf

If Content-Disposition is set to attachment, then chrome will save the file with the filename value from Content-Disposition header.

That is if the server were to respond like this:

res.setHeader(
  "Content-disposition",
  "attachment; filename=" + "server-dummy.pdf"
);
res.setHeader("Content-Type", "application/pdf");

The file would be saved as server-dummy.pdf regardless of the presence of download attribute.

KJ Sudarshan
  • 2,694
  • 1
  • 29
  • 22
2

I have a simple solution regarding this issue. You just need to put your html file into a server like Apache using xampp control and so on. Because the download attribute is properly working through a server.

<a download href="data:application/octet-stream;base64,PD94ANDSOON">Download Me</a>
Zoe
  • 27,060
  • 21
  • 118
  • 148
2

I recommend using the file-saver NPM Package to implement or force download.

  1. Install file-saver package
# install via npm
npm i file-saver

# or install via yarn
yarn add file-saver
  1. import saveAs function from file-saver
import { saveAs } from 'file-saver'
  1. use saveAs function
saveAs('https://httpbin.org/image', 'image.jpg')

References

Tunji Oyeniran
  • 3,948
  • 1
  • 18
  • 16
  • 1
    I tried most solutions on Youtube and Stackoverflow, and this is the only solution that works. It is also very easy to apply. – Cemal May 10 '23 at 13:08
1

In case anyone is having problems with this when the address of the file is different from this one, you could try to:

  1. Locally create a Blob from downloading locally the original file.
  2. Creating a URL object based on the local Blob.

It would look like this:

const outsideRes = await fetch(outsideUrl);

const blob = await outsideRes.blob();
const url = window.URL.createObjectURL(blob);

const link = document.createElement("a");
link.href = url;
link.download = "marketing-payout-report.csv";
link.click();
Philippe Fanaro
  • 6,148
  • 6
  • 38
  • 76
0

Are you looking at the files via a web server or your local filesystem - Does the browser's URL bar start with http:// or file:///? I just ran some tests in Chrome, and while it will download the file, it doesn't respect the value of the download attribute when you're using the local file.

If you start hosting it on a web server, this will start working. If you're just doing this for yourself on your computer, check out WAMP for Windows or MAMP for macOS to get started with Apache.

Sachin
  • 1,206
  • 12
  • 13
0

It won't work without a server. download attribute will do the work only when using a server (local/remote) like tomcat/xampp/wampserver...

<a href="videos/sample.mp4" download>Download Video</a>
<a href="images/sample.jpg" download>Download Image</a>

Not just only for videos or images.

-4

This can be resolved by adding target="_blank" attribute to the href.

Like this:

Save sprites.svg as 
<a target="_blank" download="somefilename.svg"
href="https://cdn.sstatic.net/Img/unified/sprites.svg"
>somefilename.svg</a>
7vujy0f0hy
  • 8,741
  • 1
  • 28
  • 33
-4

The file has to be in some zipped format!

  • Hi! Welcome to Stack Overflow! I would recommend you to check this guide on how to give a good answer https://stackoverflow.com/help/how-to-answer. Sometimes, although you might think you just gave the correct solution, you should try to explain why is this the case to provide more insight for the community. – zolastro Dec 14 '21 at 11:39
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – zolastro Dec 14 '21 at 11:39
-16

Go To Chrome Click on “Settings” and you'll see a new page pop up in your Chrome browser window. Scroll down to Advanced Settings, find the Downloads group, and clear your Auto Open options. Next time you download an item, it will be saved instead of opened automatically.

ankit
  • 7
  • 1
  • 4
    Perfect for someone who doesn’t care where his downloads go and how they are named – the opposite of the solution we are seeking. – 7vujy0f0hy Dec 22 '18 at 03:16