0

This is my code:

function downloadImage(url) {
  fetch(url, {
  mode: 'no-cors',
  })
   .then(response => response.blob())
   .then(blob => {
       let blobUrl = window.URL.createObjectURL(blob);
       let a = document.createElement('a');
       a.download = url.replace(/^.*[\\\/]/, '');
       a.href = blobUrl;
       document.body.appendChild(a);
       a.click();
       a.remove();
       })
}

var url = 'https://c4.wallpaperflare.com/wallpaper/203/636/834/minimalism-landscape-digital- 
windows-11-hd-wallpaper-preview.jpg';

downloadImage(url)

i can successfully download the image but when I open the image it's shows Sorry, Photos can't open this file because the format is currently unsupported, or the file is corrupted

When I use unsplash image url in that time it's work well. Can anyone tell me please why it's happening and how can I fix this issue.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
anjanna
  • 21
  • 1
  • 4
  • The format unsupported error can arise due to a variety of reasons , the most usual suspect in my opinion is : The [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) **Response** header being of some other MIME type. What is the value of the Content-Type header in the response of the `fetch` ? – chandresh_n Mar 20 '22 at 06:30
  • Sir can you please elaborate what you asking for because I didn't understand that – anjanna Mar 20 '22 at 07:31
  • Follow this [question](https://stackoverflow.com/questions/4423061/how-can-i-view-http-headers-in-google-chrome) to open Dev tools and look at the **Response Headers** field of the Network request to the **_url_**, we are interested in the `Content-Type` header and what is its value. – chandresh_n Mar 20 '22 at 08:58
  • content-type: image/jpeg sir.... – anjanna Mar 20 '22 at 09:14

2 Answers2

2

The issue here is the Response object , fetch is being called with mode:'no-cors', resulting in the response object to have type as "opaque" and hence using response.blob() will result into a Blob size of 0 and Blob type of "" (read more below in Response.blob()).

The mime-type is set as expected and your code works as expected but since you are making a cross origin request you are getting Response.blob() as empty and the file you subsequently save(download through anchor tag) has no data.

Read more about Response.blob()

Read more about Response.type

Read more about CORS Protocol

to validate the above try and console.log the blob like so :

function downloadImage(url) {
  fetch(url, {
  mode: 'no-cors',
  })
   .then(response => response.blob())
   .then(blob => {
       console.log(blob); //log the blob and check its size;
       let blobUrl = window.URL.createObjectURL(blob);
       let a = document.createElement('a');
       a.download = url.replace(/^.*[\\\/]/, '');
       a.href = blobUrl;
       document.body.appendChild(a);
       a.click();
       a.remove();
       })
}
chandresh_n
  • 473
  • 2
  • 4
  • Further, to understand how to use cross origin images on img tags and canvas [this MDN page](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image) is a great read. – chandresh_n Mar 20 '22 at 11:03
  • 2
    then what is the ideal solution? not using 'no-cors' is showing a failed to fetch error – Mohammed Khan Jul 16 '22 at 17:28
0

Do like this because you're not defining MIME type while downloading the file.

return fetch(urlEndpoint, options)
  .then((res) => res.blob())
  .then((blob) => URL.createObjectURL(blob))
  .then((href) => {
    Object.assign(document.createElement('a'), {
      href,
      download: 'filename.png',
    }).click();
  });

or else you can do like this

download(filename,url) {
     fetch(url, { 
  mode: 'no-cors',
  })
     .then(response => response.blob())
     .then(blob => URL.createObjectURL(blob))
     .then(uril => {
     var link = document.createElement("a");
     link.href = uril;
     link.download = filename + ".png";
     document.body.appendChild(link);
     link.click();
     document.body.removeChild(link);
     });
 }
Himanshu Maurya
  • 123
  • 1
  • 2
  • 7
  • Do I type filename with extension like myimage.jpg or without extension like myimage sir? – anjanna Mar 20 '22 at 08:38
  • Ya you have to define extension with image name like this forestpic.jpg you can see the second code above the answer and don't forget mark this right answer!! @anjanna – Himanshu Maurya Mar 20 '22 at 08:47
  • Sir getting same error... – anjanna Mar 20 '22 at 08:49
  • This error ?? Sorry, Photos can't open this file because the format is currently unsupported, or the file is corrupted @anjanna – Himanshu Maurya Mar 20 '22 at 08:50
  • yes sir Sorry, Photos can't open this file because the format is currently unsupported, or the file is corrupted.... – anjanna Mar 20 '22 at 09:11
  • As I checked now, that's CORS error maybe you have to do server side or else you can use this [cors-anywhere](https://github.com/Rob--W/cors-anywhere) @anjanna – Himanshu Maurya Mar 20 '22 at 09:15
  • Sir does it possible to do that from client side??? – anjanna Mar 20 '22 at 09:20
  • 1
    Right now I don't know that much but, you can use [cors-anywhere](https://github.com/Rob--W/cors-anywhere) deploy this code on Heroku and use it like this `'https://url-cors-url.xyz/https://c4.wallpaperflare.com/wallpaper/203/636/834/minimalism-landscape-digital-windows-11-hd-wallpaper-preview.jpg'` @anjanna – Himanshu Maurya Mar 20 '22 at 09:47