So I'm developing this app, and my client is like: "Can I have just a download button for the images pls?" And all hell broke loose.
Not long ago I started working on a resource sharing application for a client of mine. They're a design studio, and they wanted to have an app where they can distribute their work/images/source files, etc to their clients. The idea was to have a system where you can create and manage artifacts, users, user groups, and you're able to set up arbitrary access rights between them.
Basically what they needed was something that my designer colleague described as a "google drive on drugs".
So we made it. How? that's a different story.
Anyway. One day my client was like, "It's cool that we can look at the images and right-click download them, but can we have a download button as well?". I was like "sure should be fairly simple". It was not.
The first solution I found was simply using an anchor tag.
So the anchor tag has this
download attribute. Our illustrious helper w3Schools describes it with a fairly simple example:
<a href="/images/myw3schoolsimage.jpg" download="w3logo">
As simple as it could be - so I thought, and gave it a go. But my browser did not give a damn about it and just displayed the image in the same tab. What I did not calculate with was that my images and all artifacts were served from an AWS S3 bucket.
Turns out that in most browsers to be compliant with the same-origin policy, the
download attribute only works for same-origin URLs. Hence, it cannot be used to download resources served from a different origin. This is well described in this chrome feature update doc.
Anyway even if it's served from the same origin there can be problems, which need to be resolved using
Content-Disposition header. I'm not going to go into this but here's a great article about the topic.
Shortly: To inform the client that the content of the resource is not meant to be displayed, the server must include an additional header in the response. The
Content-Dispositionheader is the right header for specifying this kind of information.
The first thing I started to look for is some kind of workaround. Cross-origin image usage is well described at the corresponding Mozilla page, but I needed a download. The following StackOverflow post looked like the best approach for me. The point is that
:data are unaffected so we can use a workaround using these, then fetch and emulating the download click.
After this, a new problem came up thanks to the
Cross-Origin Resource Sharing policy. You can read up on the whole thing here. Read it. Seriously it's great and funny. I'm just putting here one quote:
I hope these links helped others who end up having similar issues.
Cover image base Designed by katemangostar / Freepik"