0

Here is a DOM like this.

<img id="this-is-the-image" src="http://192.168.1.100/Image_tmp/2016-06/d4eb8d">

I need to click a button, run a JS, and download this image file.

I have finished the button and the download script.

Some code:

```

function downloadFile(fileName, url) {
        var aLink = document.createElement('a');
        var blob = new Blob([url]);
        var evt = document.createEvent("HTMLEvents");
        getImageType(blob);
        evt.initEvent("click", false, false);
        aLink.download = fileName;
        aLink.href = URL.createObjectURL(blob);
        aLink.dispatchEvent(evt);
    }

```

I have a problem. I can only get the src "http://192.168.1.100/Image_tmp/2016-06/d4eb8d" or the name d4eb8d, but actually the image is .png or .jpg. The brower can view it, but after I save it to my computer, the file name turn to be d4eb8d, not d4eb8d.png or d4eb8d.jgp. How can I get the real type of the image so that I can specify the download_name?

Catscarlet
  • 518
  • 1
  • 5
  • 20
  • 1
    It seems, this script get the url-string data instead of img-data. I think FileReader can only read file from local. – Catscarlet Jun 21 '16 at 07:42
  • 1
    _"It seems, this script get the url-string data instead of img-data. I think FileReader can only read file from local."_ Was curious what purpose of `new Blob([url])` was? You can use `XMLHttpRequest()` to retrieve image as `Blob`, then use `FileReader()` with `response` from `XMLHttpRequest()` as parameter to `.readAsDataURL()`; see http://plnkr.co/edit/To4uZXL8PUph9qG3azvZ?p=preview or use `response.type` – guest271314 Jun 21 '16 at 07:52
  • See version 2 at plnkr http://plnkr.co/edit/To4uZXL8PUph9qG3azvZ?p=preview, using `XMLHttpRequest()` `.response.type.split("/")[1]` , where `.response` is `Blob` returned from request for image, instead of `FileReader()` – guest271314 Jun 21 '16 at 07:58
  • You were right. My Blob([url]) was not the right blob. I just realize it. – Catscarlet Jun 21 '16 at 08:12
  • What is `url`? Were you passing the `img` `src` as `url` to `new Blob([url])`? – guest271314 Jun 21 '16 at 08:17
  • Yes. I made a mistake. Actually I'm going to give up. It seems that It has to be done by XMLHttpRequest(), however the img on the page is from another site, which require Access-Control-Request. What's worse, these JS is running in a application made by my company, I can't just execute any request directly. To make some request, Only the private function of the application is allowed, and it doesn't support any params or responseType. I can do nothing without XMLHttpRequest(). – Catscarlet Jun 21 '16 at 08:56
  • Try using `canvas` element, `FileReader()` approach; see http://stackoverflow.com/questions/32880641/canvascontext2d-drawimage-issue-onload-and-cors – guest271314 Jun 21 '16 at 13:49
  • Sorry. The isn't handled by me. I can't change the . And without XMLHttpRequest() to read the img, I can't do anything. – Catscarlet Jun 21 '16 at 14:57
  • I tried canvas, and I got 'Cross-Origin Resource Sharing policy' and 'Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.(…)'. I give up. – Catscarlet Jun 22 '16 at 07:37
  • Did you try at the same domain? Try using `fetch` to retrieve the `Content-Type` header – guest271314 Jun 22 '16 at 08:00
  • Another option would be to try using YQL – guest271314 Jun 22 '16 at 08:08

3 Answers3

1

You can use XMLHttpRequest() with .responseType set to "blob" to request image file; blob.type.split("/")[1] where type is MIME type of Blob, [1] after .split() would be jpg, jpeg, png or other image type

  window.onload = function() {
    var aLink = document.querySelector("a");
    var fileName = "image";
    var request = new XMLHttpRequest();
    request.responseType = "blob";
    request.open("GET", "http://example.com/d4eb8d");
    request.onload = function() {
    var blob = this.response;
      var type = blob.type.split("/")[1];
      console.log(type);
      var evt = document.createEvent("HTMLEvents");
      evt.initEvent("click", false, false);
      aLink.download = fileName + "." + type;
      aLink.href = URL.createObjectURL(blob); 
      aLink.dispatchEvent(evt);
    }
    request.send()
  }

plnkr http://plnkr.co/edit/To4uZXL8PUph9qG3azvZ?p=preview

guest271314
  • 1
  • 15
  • 104
  • 177
0

Are you sure that new Blob([url]) will return blob with image content? not a text file with this content http://192.168.1.100/Image_tmp/2016-06/d4eb8d?

As i know you can turn image link to blob only by read this with XHR => How to get a file or blob from an object URL?

then when you will have blob, get file type from blob.type. And attach extension

var ext ="";
switch(blob.type){
   case "image/jpeg":
        ext=".jpg";
        break;
   case "image/png":
        ext=".png";
        break;
   case "image/gif":
        ext=".gif";
        break;
}
aLink.download = fileName + ext;
Community
  • 1
  • 1
Alex Nikulin
  • 8,194
  • 4
  • 35
  • 37
0

You have an instance of HTMLImageElement and, as far as I can tell from the documentation, it doesn't have any property with the image type.

You could grab the URL, launch an AJAX call and get the Content-Type header, from which it should be easy to figure out a file extension... assuming the remote server provides the information (if it doesn't, you have a different problem). The XMLHttpRequest object has a .getResponseHeader() method.

You algo have the poor-man's solution of changing window.location to the picture URL but of course there's no way to force a download.

Last but not least, you can build a little server-side script that downloads the file on the server and prepares all the details.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360