在前端开发中,有时候我们需要实现点击图片后直接下载的功能。本文将介绍两种方法来实现这一功能:
- 同源使用
<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.width canvas.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 对象的 URL a.href = url // 模拟点击事件触发下载 a.dispatchEvent(event) // 释放 Blob 对象的 URL URL.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',这样就可以避免跨域问题。
版权归原作者 turbo夏日漱石 所有, 如有侵权,请联系我们删除。