今日天气晴朗、万里无云、微风,我正努力地摸鱼(啊呸,搬砖) ...... 突然,产品经理闪现到了我的背后,静静地说道 “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, 0, 0, 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 属性存在一定的限制,以上方式虽可实现在当前页面下载保存图片,但各有优劣。
参考
如果您有任何想法,欢迎在留言区和我留言,或者关注公众号,交流探讨。