图片跨域了怎么下载?

2024年04月27日 01:43  ·  阅读 467


下载图片主要利用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>


评论
全部评论