canvas 图片跨域解决方案

2,778 阅读1分钟

图片为什么会出现跨域这里不再赘述、不明白的同学自行百度。在这里直接提供可行的解决方案

利用CORS(跨域资源共享)

1、服务器端设置CORS

Access-Control-Allow-Origin: *
或者
Access-Control-Allow-Origin: www.example.com

例如:

# 本地nginx测试配置
location ^~ /static/ {
    root html;
    add_header Access-Control-Allow-Origin *;
}

2、使用图片CORS实现canvas截图

// 使用示例1
let ctx = canvas.getContext('2d');
let _img = new Image();
_img.crossOrigin = '';
_img.onload = function () {
    canvas.width = _img.width;
    canvas.height = _img.height;
    ctx.drawImage(_img, 0, 0, _img.width, _img.height)
    newImg.setAttribute('src', canvas.toDataURL('image/png'))
}
_img.src = img.src;

注意: 如果出现 Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 请检查是否设置 img.crossOrigin

IE10浏览器不支持CORS解决方案:

// 使用示例2 
proxyImage(/* 你的图片src */)

function proxyImage(url) {
  var xhr = new XMLHttpRequest();
  xhr.onload = function () {
    if (xhr.status === 200) {
      var render = new FileReader();
      render.onload = function () {
        var ctx = canvas.getContext('2d');
        var _img = new Image();
        _img.onload = function () {
          canvas.width = _img.width;
          canvas.height = _img.height;
          ctx.drawImage(_img, 0, 0, _img.width, _img.height);
          // 截图
          newImg.setAttribute('src', canvas.toDataURL('image/png'));
        };
        _img.src = render.result;
      };
      render.onerror = function () {
        console.log('in render.onerror');
      };
      render.readAsDataURL(xhr.response);
    }
  };
  xhr.onerror = function () {};
  xhr.open('get', "".concat(url, "?_=").concat(Date.now(), "&responseType=blob"));
  xhr.responseType = 'blob';
  xhr.send();
}

特别说明: proxyImage()方案来源于html2canvas.js