Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

href tag download attribute - how to make it force download of externally hosted image?

I want to make a <a href link which, when clicked, forces your browser to open a "Save As" dialogue. The use of the HTML5 download attribute should have this behavior on all modern browsers.

When the target is an externally hosted image file, this does not work. The <a href link will navigate to the image instead of downloading it. (Tested using images hosted on Imgur and Tumblr)

<a href="https://i.stack.imgur.com/440u9.png" download>
  <img src="https://i.stack.imgur.com/440u9.png" width="200"/>
</a>

Similar HTML code does work if the image is hosted locally on your server, for example

<a href="440u9.png" download>
  <img src="440u9.png" width="200"/>
</a>

Another example - this will work in the W3Schools Tryit Editor, but will not work if you copy the HTML to another sandbox like JSFiddle

<a href="https://www.w3schools.com/images/myw3schoolsimage.jpg" download>
  <img src="https://www.w3schools.com/images/myw3schoolsimage.jpg" width="104" height="142">
</a>


Possible causes explored:

  • Bad image URL: no, the URL is good, you can open the URL as a plain image in your browser
  • Links with https: can't be used this way due to security: no, a URL with https: is good if the URL points to the same domain, tested in W3Schools Tryit Editor
  • Server-side redirect: an http://... link can be redirected to https://... so maybe that could be a cause of failure, but the https://... link also does not work
  • Suppression of download attribute on server by specific hosts? is that even possible? the download attribute should control only client-side browser action surely?

Any workarounds? I have tried Javascript download methods discussed here and here but these all eventually involved a browser action similar to clicking on an href link.

Excellent in-depth discussion of download links including application/force-download setting in PHP on the server

Related StackOverflow question: Force external download url (answer seems to be incorrect)

like image 900
radfast Avatar asked Sep 23 '18 11:09

radfast


Video Answer


1 Answers

Turns out the answer is that this cannot be done in the way I was asking. Modern browsers prevent cross-domain downloads as a security feature.

See: Making Firefox and Chrome download image under a specific name

Force <a download /> to download image instead of opening url link to image

If the download must be byte-identical to the original file, the only solutions I can find right now are:

  1. The server must first use an httpClient request to get the target resource, save it to disk locally on the server, then provide an <a href='tmp.jpg' download> link with the URI being that saved file. Or, some server frameworks are able to create a bytestream simulating file access, in which case the resource could be cached to memory instead of saving to disk.

    Drawbacks: data cost equal to twice the filesize (once in, once out), roundtrip delay, use of server memory/filesystem. Probably every possible file with a download link has to be stored locally on the server before the page is served (or maybe it can be done asynchronously using websockets, serving the file after the user clicks the download link, but with a delay). For large files or high usage servers these are serious drawbacks.

  2. Open the target URL in a new tab, and let the client switch to that tab, and manually right-click and Save As...

    Drawbacks: this is exactly what we are trying to avoid!

I'm still wondering if there is some hack for this, like giving a local URL and having the server redirect a request for that particular resource to the external site.

like image 87
radfast Avatar answered Oct 19 '22 22:10

radfast