首页 > 解决方案 > 如何创建一个从 API 获取图像并使用 ReactJs 下载到本地的按钮

问题描述

我需要一个将图像下载到本地的按钮。但是这些图像来自 Unsplash API。

我找到了一个 HTML download attribute, LIVE DEMO

<p>Click on the image to download it:<p>
<a href="/images/myw3schoolsimage.jpg" download>
  <img src="/images/myw3schoolsimage.jpg" alt="W3Schools" width="104" height="142">
</a>

在此处输入图像描述

但是如果我想在 React 中使用这种方法是行不通的。原因是我想从 Unsplash API 下载的图像因此无法正常工作!但是,如果我尝试下载属于我的项目目录的本地图像,它就成功了!

import style from "./style.module.css";
import cn from "classnames";
import { BiDownArrowAlt, BiPlus } from "react-icons/bi";

import logo from "../../assets/images/Logo.png";

const ImageCard = ({ image }) => {
    return (
        <div className={style.image}>
            {/* {  Download Button } */}
            <a href={logo} download target="_blank">
                <span className={cn(style.button, style.downloadButton)}>
                    <BiDownArrowAlt className={style.downloadIcon} />
                </span>
            </a>
        </div>
    );
};

这是可行的,但我的照片来自 API。

我在 StackOverflow 中搜索了这个主题,发现了这个问题。但是这种方法是行不通的。下载图像但图像不起作用。

在此处输入图像描述

import style from "./style.module.css";
import cn from "classnames";

import { BiDownArrowAlt, BiPlus } from "react-icons/bi";

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);
        });
};

const ImageCard = ({ image }) => {
    return (
        <div className={style.image}>
            {/* {  Download Button } */}
            <a
                href={image.links.download}
                download
                onClick={(e) => download(e)}
                target="_blank"
            >
                <span className={cn(style.button, style.downloadButton)}>
                    <BiDownArrowAlt className={style.downloadIcon} />
                </span>
            </a>
    );
};

export default ImageCard;

我该如何解决这个问题请帮助我!

标签: javascripthtmlreactjs

解决方案


这是香草javascript中的解决方案

const IMG_URL = "https://media.gettyimages.com/photos/closeup-network-space-picture-id1013942164?s=612x612";

function toDataURL(url) {
  return fetch(url).then((response) => {
          return response.blob();
      }).then(blob => {
          return window.URL.createObjectURL(blob);
      });
}

async function download() {    
    const a = document.createElement("a");
    a.href = await toDataURL(IMG_URL);
    a.download = "myImage.png";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}

const link = document.querySelector('#link');

link.addEventListener('click', () => {
  download()
})
<a href="#" id="link">Download</a>

它在这里被阻止,但你可以看到它在小提琴https://jsfiddle.net/f5061vbc/1/上工作


推荐阅读