求star

开源不易,喜欢请点个star吧

Ocean Han
581 字
3 分钟
实现图片下载的常用方法
2023-04-26

后端配合下载#

TIP

​ 需要下载的图片是后端生成并返回的场景。

​ 设置返回的响应数据类型 responseType: ‘blob’

export const exportPNG = async (token?: string, id?: string, height?: string) => {
  // ... 
  const pngData = await getPNGAsync(params);
  if (pngData.status) {
    ElMessage.warning('下载失败,请尝试重新导出');
    return;
  } else {
    const blob = new Blob([pngData], { type: 'application/image' });
    const downloadElement = document.createElement('a');
    const href = window.URL.createObjectURL(blob); //创建下载的链接
    downloadElement.href = href;
    downloadElement.download = `${fileName}.png`; //下载后的文件名,根据需求定义
    document.body.appendChild(downloadElement);
    downloadElement.click(); //点击下载
    document.body.removeChild(downloadElement); //下载完成移除元素
    window.URL.revokeObjectURL(href); //释放掉blob对象
  }
};

纯前端下载#

TIP

​ 需要下载的图片是,本地页面的图片或者一个图片的URL的场景

同源的图片#

TIP

​ 同源的图片可以直接利用a标签进行下载,给a标签设置download(H5新增的属性)属性可以:指定下载后的文件名称,并告诉浏览器下载该URL,而不是访问其指向的内容

<img src="./axios.png" alt="" style="height: 200px;" >
<a href="./axios.png" download="axios.png" target="_blank">点击下载</a>

非同源的图片#

TIP

​ 跨域的图片不能直接使用a标签下载,可通过以下几种方式:

1. 利用canvas#

TIP

​ 因为Base64编码不受同源策略限制,所以可以利用canvas的toDataURLAPI得到图片的Base64编码,然后再利用a标签设置download属性下载

const downloadImage = (imgUrl) => {
    const image = new Image()
    const fileName = imgUrl && imgUrl.split('/').pop()	// 文件名
    //	解决跨域 Canvas 污染问题
    image.setAttribute('crossOrigin', 'anonymous');
    image.onload = function(e) {
        const canvas = document.createElement('canvas')
        canvas.width = image.width
        canvas.height = image.height
        const context = canvas.getContext('2d')
        context.drawImage(image,0,0,image.width,image.height)
        //	得到图片的Base64编码数据
        const url = canvas.toDataURL('image/png')
        const a = document.createElement('a')
        const event = new MouseEvent('click')
        a.download = fileName || 'img'
        a.href = url
        a.dispatchEvent(event)
    }
    image.src = imgUrl
}
WARNING

需要注意的是,图片加载时异步的,在转化成dataURL前必须先确保图片加载到,否则让canvas立即执行绘制可能失败,所以我们应该把绘制canvas和转换Base64编码的过程放在onload中

2. 创建XHR对象发起请求#

const downloadIamge2 = (imgUrl) => {
      event.returnValue = false;  //  阻止默认事件
      const x = new XMLHttpRequest();
      x.open("GET", imgUrl, true);
      x.responseType = 'blob';	//	设置响应类型
      const fileName = imgUrl && imgUrl.split('/').pop()	// 文件名
      x.onload = function (e) {
        const url = window.URL.createObjectURL(x.response)
        const a = document.createElement('a');
        a.href = url
        a.download = fileName || 'img'
        a.click()
      }
      x.send();
    }
实现图片下载的常用方法
https://blog.oceanh.top/posts/frontend/实现图片下载的常用方法/
作者
Ocean Han
发布于
2023-04-26
许可协议
CC BY-NC-SA 4.0
最后修改时间
2024-08-10 10:08:49