1

I'm trying to make simple button which when is clicked will download image. Currently when I click it is open image on blank page where you should click "Save as.."

How can I "force" the browser to download it?

This is current image and button

<img src="{{ $thumb }}" class="img-responsive">             
<a type="submit" download="{{ $thumb }}" href="{{ $thumb }}" class="btn btn-primary"> 
    Download Image
</a>

I've tried:

download="{{ $thumb }}"

Also

download="{{ $thumb }}" target="_blank"

Also tried to put the <img...> tag inside <a href..> tag and still doesn't work.

  • Is your image on the same domain or is it a cross origin image? because as of latest update, `download` attribute wont work for cross origin image urls – Jones Joseph Apr 26 '18 at 12:07
  • It's on another domain. –  Apr 26 '18 at 12:08
  • But there is a site which you still can download an image from another domain. I guess it's possible somehow. –  Apr 26 '18 at 12:16
  • Yes it is.. if that domain allows cross origin requests which most domains won't allow.. Check my answer below – Jones Joseph Apr 26 '18 at 12:19
  • I don't think that the site which I shared below is allowed to download images like this from fb. –  Apr 26 '18 at 12:26

5 Answers5

3

You can try this to force download an image.
However you cannot download something that is not on your domain, unless you are using a domain which accepts cross origin requests (Eg:Imgur)

You may use the 'download' attribute of HTML5 but still you won't be able to load in cross origin image.

Also the below method will support legacy browsers as well

function forceDownload(link){
    var url = link.getAttribute("data-href");
    var fileName = link.getAttribute("download");
    link.innerText = "Working...";
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = function(){
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(this.response);
        var tag = document.createElement('a');
        tag.href = imageUrl;
        tag.download = fileName;
        document.body.appendChild(tag);
        tag.click();
        document.body.removeChild(tag);
        link.innerText="Download Image";
    }
    xhr.send();
}
<a href="#" data-href='https://i.imgur.com/Mc12OXx.png' download="Image.jpg" onclick='forceDownload(this)'>Download Image</a>

Note: You cannot force the browser to show a 'Save As' dialog as it is based upon what the user preferences are.

Jones Joseph
  • 4,703
  • 3
  • 22
  • 40
  • Thanks. This seems to work and it is showing the `Save File` prompt. Are you aware how this is done because it doesn't show the Save as prompt - [DownloadGram](https://downloadgram.com/) –  Apr 26 '18 at 12:23
  • Well, we can't force the browser to show a 'Save dialog'. It works based on user preference. – Jones Joseph Apr 26 '18 at 12:27
  • Oh, I see. I've tried on different browser and it's downloaded without prompt. Thanks for clarifications. –  Apr 26 '18 at 12:27
1

<a href="/images/img.jpg" download> By adding this you can download image automatically by just one click
note: The download attribute is not supported in Edge version 12, IE, Safari 10 (and earlier), or Opera version 12 (and earlier).

Lex V
  • 1,414
  • 4
  • 17
  • 35
  • 1
    It doesn't work. I've tried it also before adding the image inside `download=""` –  Apr 26 '18 at 12:03
  • Have you tried `download` without the `=""` ? This answer should work. – McVenco Apr 26 '18 at 12:04
  • Yes, I've tried all variations which I found of `download`. Seems like is disabled on all browser and the question is how can be done now, –  Apr 26 '18 at 12:05
  • Just pure curiousity, since this very bad practise (think about the "forced download" you have without confirming that you actually want it or misclicked, and next to that, it can be utilized to download stuff to your pc / phone to attempt to hack it ... so i think its only good it's been disabled) – Dorvalla Apr 26 '18 at 12:07
  • Yes, but the user sees the actual image before download it. It doesn't download something that is not visible. Or I'm wrong here? –  Apr 26 '18 at 12:09
0

Try this

<img src="{{ $thumb }}" class="img-responsive">             
<a href="{{ $thumb }}" class="btn btn-primary" download> 
    Download Image
</a>
Jasbir
  • 374
  • 5
  • 15
0

Another option is using the fetch methods

function downloadFile(elmnt) {
  
  const link = elmnt
  const url = 'https://assets.ctfassets.net/cfexf643femz/8rnHaKLBl6L4t1LmuV0OG/03d7ee1d08119fce2a3f80b93b97ab05/Lagos_de_Torca_en_cifras.pdf'
const options = {
  'Accept': 'application/json',
  'Content-Type': 'application/json'
};
  
 fetch(url, options)
  .then( response => {
    response.blob().then(blob => {
        let url = window.URL.createObjectURL(blob);
        let a = document.createElement('a');
        a.href = url;
        a.download = "file.pdf";
        a.click();
      });
    }); 
}

https://codepen.io/edgarv09/pen/KKabVob example

0

Based on the selected answer above by Jones Joseph, I modified his code to not require an anchor tag in the html to link from. Rather I used a button and in AngularJS passed the name of the photo file as a parameter to ng-click.

The HTML

<button ng-click="MainController.newDownload(MainController.oPhoto.filename)">Download Photo</button>

The JavaScript:

    this.newDownload = function(filename){
    var url = 'photos/' + filename
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = function(){
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(this.response);
        var tag = document.createElement('a');
        tag.href = imageUrl;
        tag.download = filename;
        document.body.appendChild(tag);
        tag.click();
        document.body.removeChild(tag);
        link.innerText="Download Image";
    }
    xhr.send();
  }

Works in Chrome 107.0.5304.122 (Official Build) (64-bit)

Harvey Mushman
  • 615
  • 1
  • 11
  • 23