利用 a 标签实现图片下载

476 阅读1分钟

今日天气晴朗、万里无云、微风,我正努力地摸鱼(啊呸,搬砖) ...... 突然,产品经理闪现到了我的背后,静静地说道 “x工,之前的某个需求给咱再加一个下载图片的功能”,听罢,我摸了摸手边的卷笔刀,拍案而起 ...... 愉快地说道,包在我身上。

于是乎立马祭出了开发神器 VSCode ,三下五除二利用 a 标签搞定需求,正要开心的测试时,发现打开了一个新的页面 Tab 且并未执行下载,怎么和预想的差别这么大?我不李姐 ...... 🤔

<!-- 短小简洁,但啪啪打脸 -->
<a href="https://p.com/fe/assets/share.png" download />

如何才能实现在当前页面下载图片并保存呢?请宁耐片刻,接着往下看,翻查了 MDN 上的释义说明(引用如下)后发现,

Note:download only works for same origin URLs, or the blob: and data: schemes.

方法1:采用 blob 格式来实现下载,

// 将 URL 转换为 Blob: URL 格式
const typedURLToBlob = async url => (
  fetch(url).then(res => {
    return res.blob()
  }).then(blob => {
    return URL.createObjectURL(blob)
  })
)

const blobUrl = await typedURLToBlob('https://p.com/fe/assets/share.png')
// 结果 blob:https://p.com/78305bc0-9c1e-4b2a-bcef-6ee42e9239a1
<!-- 增长,战斗力也增强 -->
<a href="blob:https://p.com/78305bc0-9c1e-4b2a-bcef-6ee42e9239a1" download />

方法2:采用 data 格式实现下载,

// 利用 canvas 转 Base64
const drawBase64Image = (image, type = 'image/png') => {
  let canvas = document.createElement('canvas')
  canvas.width = image.width
  canvas.height = image.height
  
  let ctx = canvas.getContext('2d')
  ctx.drawImage(image, 00, image.width, image.height)
  return canvas.toDataURL(type)
}

const getBase64Image = url => {
  let image = new Image()
  image.src = url
  // 避免抛出安全错误,此处需设置允许跨域访问
  image.crossOrigin = 'anonymous'
  image.onload = () => {
    drawBase64Image(image)
  }
}
<!-- 巨长,估摸着得缠腰上 -->
<a href="data:image/png;base64,iVBORw0K..." download />

可见 a 标签自带 download 属性存在一定的限制,以上方式虽可实现在当前页面下载保存图片,但各有优劣。

参考

如果您有任何想法,欢迎在留言区和我留言,或者关注公众号,交流探讨。

扫码_搜索联合传播样式-标准色版.png