目录
方法一:同源使用标签下载图片
方法二:跨域使用将canvas上的内容转换为Blob对象并下载
在前端开发中,有时候我们需要实现点击图片后直接下载的功能。本文将介绍两种方法来实现这一功能:
- 同源使用
<a>
标签下载图片- 跨域使用将
canvas
上的内容转换为Blob
对象并下载。
方法一:同源使用
<a>
标签下载图片在同源情况下,我们可以通过创建一个
<a>
标签,设置其href
属性为图片的链接,然后设置download
属性为图片的文件名,就可以实现点击图片下载的功能。<a href="image.jpg" download="image.jpg"><img src="image.jpg" alt="Image"> </a>
但当出现请求下载资源跨域时这个方法就不能实现效果了
方法二:跨域使用将
canvas
上的内容转换为Blob
对象并下载在跨域情况下,由于浏览器的安全策略限制,直接下载图片可能会受到限制。我们可以通过将图片绘制到
canvas
上,然后将canvas
上的内容转换为Blob
对象,最后通过创建<a>
标签来实现下载。代码中有详细注释:
// 接收一个图片链接作为参数 function download(link: string) {// 创建新的图片对象const img = new Image()// 设置图片跨域属性为匿名img.setAttribute('crossOrigin', 'Anonymous')// 图片加载完成后执行回调函数img.onload = function () {// 创建一个新的画布元素const canvas = document.createElement('canvas')// 获取画布的2D上下文const context = canvas.getContext('2d')// 判断是否成功获取到画布上下文if (context) {// 设置画布的宽度和高度与图片一致canvas.width = img.widthcanvas.height = img.height// 在画布上绘制图片context.drawImage(img, 0, 0, img.width, img.height)// 将画布内容转换为 Blob 对象canvas.toBlob((blob) => {// 判断是否成功生成 Blob 对象if (blob) {// 创建一个临时链接用于下载const url = URL.createObjectURL(blob)const a = document.createElement('a')const event = new MouseEvent('click')// 设置下载的文件名a.download = 'default.png'// 设置链接地址为 Blob 对象的 URLa.href = url// 模拟点击事件触发下载a.dispatchEvent(event)// 释放 Blob 对象的 URLURL.revokeObjectURL(url)} else {console.error('生成 Blob 失败')}})} else {console.error('获取 Canvas 上下文失败')}}// 设置图片的 src 属性,并在链接后添加时间戳以避免缓存img.src = `${link}?v=${Date.now()}` }
注:
在canvas中绘制了来自其他域名的图片时,浏览器会认为这个canvas被“污染”(tainted),即受到了跨域限制。在这种情况下,浏览器会禁止使用toBlob()方法导出这个canvas作为Blob对象。
为了解决这个问题,可以在加载图片时设置图片的crossOrigin属性为'Anonymous',这样就可以避免跨域问题。