581 字
3 分钟
实现图片下载的常用方法
后端配合下载
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(); }