I want to create a download button which will download image from api, I was able to do that but then got stuck in a problem . whenever I click on download button it does download the image but it also open the image in that page which makes it to leave the main page. I want it so that it won't open the image only download the image .
here is what I did
const download = (e) => {
console.log(e.target.href);
fetch(e.target.href, {
method: "GET",
headers: {},
})
.then((response) => {
response.arrayBuffer().then(function (buffer) {
const url = window.URL.createObjectURL(new Blob([buffer]));
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "image.png"); //or any other extension
document.body.appendChild(link);
link.click();
});
})
.catch((err) => {
console.log(err);
});
};
<div className="row">
<div className="col-sm-4 text-center">
{quote?.map((items) => (
<div style={{ width: "18rem;" }}>
<img src={items.img} alt="..." />
<div >
<h5 style={{ textTransform: "capitalize" }} >
{items.name.replace(/_/g, " ")}
</h5>
<p >{items.disc}</p>
<Button
variant="outlined"
href={items.img}
onClick={ download }
>
Download
</Button>
</div>
</div>
))}
</div>
</div>
CodePudding user response:
The client side solution would only work if the requested image is NOT blocked by CORS policy.
async function download(url) {
const a = document.createElement("a");
a.href = await toDataURL(url);
a.download = "myImage.png";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
function toDataURL(url) {
return fetch(url)
.then((response) => {
return response.blob();
})
.then((blob) => {
return URL.createObjectURL(blob);
});
}
function onClick() {
download("https://github.githubassets.com/images/modules/profile/badge--acv-64.png");
}
Complete working demo at codesandbox
If you have server access you can just add a Content-disposition
header & then simply doing window.open(url, '_self')
would download the image -
NGINX - add_header Content-disposition "attachment; filename=$1";