Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

html

<a download='file' href="https://tinyjpg.com/images/social/website.jpg">
  Download
</a>

Is there a way to force the download of a file instead of opening the file in a new window? Right now if the file is a URL, like the example below it won't be downloaded and will open in a new window.

like image 566
gnifrus Avatar asked Apr 09 '18 15:04

gnifrus


People also ask

How do I download a link instead of opening it?

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

How do you link a downloaded image in HTML?

Strip the path, e.g using $file = pathInfo($_GET['file'] and then assemble the path by appending some known path with $file['basename']. If you need to provide files from various folders, use path tokens in your request, which you then map to the actual path in your download function.


2 Answers

You may be bitten by the fact that Firefox and Chrome 65+ only support same-origin download links, probably as a security measure.

Source: https://caniuse.com/#feat=download (see "Known issues" tab)

The Web Hypertext Application Technology Working Group (WHATWG) recommends that in cross-origin scenarios (as in your example), the web server that is hosting the image/file in question needs to send a Content-Disposition HTTP header for download= to be honored.

Source: https://html.spec.whatwg.org/multipage/links.html#downloading-resources


In short:

You can only use <a download='...'></a> to force download of an image/file, if:

  1. the html and the image/file are hosted on the same domain,
    or
  2. the image/file is on a different domain, and that server also says it should be downloaded.
like image 180
Peter B Avatar answered Sep 28 '22 01:09

Peter B


Maybe you have solved in the meanwhile, but since you are hosting the files on S3 (see comments on Peter B's answer), you need to add a signature to the files url and set the ResponseContentType to binary/octet-stream by using the aws sdk. I am using Node so it becomes:

const promises = array.map((item) => {
        const promise = s3.getSignedUrlPromise('getObject', {
            Bucket: process.env.S3_BUCKET,
            Key: key, //filename
            Expires: 604800, //time to expire in seconds (optional)
            ResponseContentType: 'binary/octet-stream' 
        });

        return promise;
    });

    const links = await Promise.all(promises);

I hope this helps.

like image 25
Mattia Rasulo Avatar answered Sep 28 '22 02:09

Mattia Rasulo