Let's say you're trying to add a feature to your site or app to allow users to download an image upon clicking a button. Should be pretty straight forward right? I thought so myself as I needed to add this feature when building an internal media library tool at Discovery.
I tried adding this feature by just adding the download attribute to an anchor tag and setting the href attribute to the image url (cross-origin url).
<a href='URL_HERE' download>Download image</a>
Turns out that Chrome started ignoring download attributes that pointed to cross origin urls.
To solve this, we'll take advantage of the browser built in fetch method. You'll need to add an event listener to the element that you want to trigger the image download and call the below function:
// Using fetch
async function downloadImage(imageSrc) {
const image = await fetch(imageSrc)
const imageBlog = await image.blob()
const imageURL = URL.createObjectURL(imageBlog)
const link = document.createElement('a')
link.href = imageURL
link.download = 'image file name here'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
The imageSrc function parameter represents the cross origin image url.
- First, we use fetch to get the ReadableStream data of the image
- Next, we call the blob method provided by fetch to get the raw image data
- Third, we use the URL Web API to call the createObjectURL static method to create a URL that represents the image's download URL
- Finally, an anchor element is created to set the new url to the href attribute. You can also set the name of the file by setting the download attribute of the anchor element. Last, we append the anchor element we created to the DOM and trigger a click to download the image and then quickly remove the anchor from the document.
And there you go! You now have the ability to download images on the trigger of a function!
I hope this helped and was useful for you!
This post can also be found at sapanbodiwala.com/blog
Top comments (14)
Mota bhai this doesn't work when there's CORS restriction!!!
It will fail at the first fetch call itself.
it works!! thanks alot
Thanks dude!
Not Helpful
You made my day man! Thank you for sharing
It works well. Thanks.
Maybe someone solved the CORS problem?
What if image can't be fetched from its source ? it there any other way to get image from DOM ?
best one thanks 👍
Thanks for the solution!