下载图片主要利用a标签的download属性,但如果图片跨域,点击a标签时,不会下载href指定的图片,而是跳转到href指定的网页,因此需要先本地化图片,才能下载图片
第一步,图片本地化
以下两种方法都需要图片允许跨域,需要服务器配置跨域响应头。若是其他服务器,可以考虑让后端人员进行一次转发。或者前端设置跨域代理。
方法一:手动发起请求,获取图片的blob
- 将responseType设置为blob,请求图片,获取图片的blob对象
- 利用URL.createObejectURL方法,为blob图片创建链接
function getLocalUrl(url) {
// 因为发送请求是异步执行的,所以使用promise包裹
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
// 要求响应格式的是blob
xhr.responseType = 'blob'
xhr.open('get', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 请求成功,URL.createObjectURL将blob对象转换为本地url
resolve(URL.createObjectURL(xhr.response))
}
}
xhr.send()
})
}
方法二:利用canvas将图片转换为base64格式
- 先将图片插入到canvas
- 利用canvas的toDataURL方法,将图片转为base64
function getLocalUrl(url) {
// 图片加载非同步,需要promise包裹
return new Promise((resolve, reject) => {
// 创建图片,并将图片属性设置为可跨域
const img = document.createElement('img')
// 不设置该属性canvas无法将图片转为base64
img.setAttribute('crossorigin', 'anonymous')
img.src = url
img.onload = function () {
const canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
const ctr = canvas.getContext('2d')
// 画图
ctr.drawImage(img, 0, 0, img.width, img.height)
resolve(canvas.toDataURL())
}
})
}
第二步,使用a标签的download属性下载图片
- 给a标签设置download属性,属性值是图片的名称
- 给a标签的href属性赋值
<a href="" download="yy.jpg" id="down">下载图片</a>
<script>
const a = document.getElementById('down')
getLocalUrl(url).then(res => {
a.href = res
})
</script>