为什么图片无法跨域下载却可以右键另存为

function downloadImage(src) {
  const a = document.createElement('a')
  const urlArr = src.split('/')
  const name = urlArr[urlArr.length - 1]
  a.download = name
  a.style.display = 'none'
  const image = new Image()
  image.crossOrigin = "Anonymous"
  image.src = src + '?v=' + Math.random()
  image.onload = () => {
    const base64 = getBase64Image(image)
    a.href = base64
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
  }
  const getBase64Image = (img) => {
    const canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    const ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, img.width, img.height);
    const ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
    const dataURL = canvas.toDataURL("image/" + ext);
    return dataURL;
  }
}

通过以上方式下载https://img.3dmgame.com/uploa...
会出现跨域错误,

为什么图片可以另存为呢?

阅读 4.2k
3 个回答

因为你直接点连接,相当于单独窗口打开,服务器端可能有防盗链处理判断,这种相当于盗链而被拒绝。
另存为是在当前浏览下,已经下载数据的保存,不会触发这样的机制。

服务器端要设置允许跨域:access-control-allow-origin: *;
不然前端设置 image.crossOrigin = "Anonymous" 是无效的;

你试下这个:

downloadImage('http://n.sinaimg.cn/photo/transform/700/w1000h500/20201106/1ad8-kcpxnwv8925892.png')

image

跨域是浏览器为了防范恶意代码执行做的限制,跨域的代码会被认为是危险的,除非服务端在头里使用 access-control-allow-x 明确指定,某域是安全的,才会执行。
这里防范的是「在用户不知道的情况下进行危险操作」。
但是用户手动保存那是人的自由意志,浏览器就没有必要去限制了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题