下载图片主要利用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()// 要求响应格式的是blobxhr.responseType = 'blob'xhr.open('get', url, true)xhr.onreadystatechange = function () {if (xhr.readyState === 4) {// 请求成功,URL.createObjectURL将blob对象转换为本地urlresolve(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无法将图片转为base64img.setAttribute('crossorigin', 'anonymous')img.src = urlimg.onload = function () {const canvas = document.createElement('canvas')canvas.width = img.widthcanvas.height = img.heightconst ctr = canvas.getContext('2d')// 画图ctr.drawImage(img, 0, 0, img.width, img.height)resolve(canvas.toDataURL())}})}
第二步,使用a标签的download属性下载图片
给a标签设置download属性,属性值是图片的名称
<a href="" download="yy.jpg" id="down">下载图片</a><script>const a = document.getElementById('down')getLocalUrl(url).then(res => {a.href = res})</script>
