Mr.Yuan Mr.Yuan

苟正其身矣,于从政乎何有?不能正其身,如正人何?

目录
canvas 图片跨域问题
/      

canvas 图片跨域问题

image.png

前言

先祝大家圣诞节快乐🎅🎁 🎄

最近公司也是趁圣诞节想出个活动:给用户测试属性和圣诞专属头像的活动。并把结果生成为图片保存下来 huaji

开发中图片与网页的域名不同,造成了很多问题在此记录。

  • 图片 xhr 跨域加载报错
  • 字体跨域绘制时不能正常使用字体
  • 绘制了 canvas 但不能调用 toDataUrl 方法

填坑开始了 doge :

问题描述

图片加载跨域

1. 报错信息

image.png

原因

🙈 图片跨域禁止加载(xhr方式)。

2. toDataURL 无法调用

Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.  
'xxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.  

image.png

原因

canvas 中如果绘制了外部(其它域名下)的图片,则 canvas 会被标记为 “不安全” 的这个时候 canvas 会禁止调用诸如: toDataURL , toBlob 方法 🐒 。

解决方式

服务端配置

Access-Control-Allow-Origin: *

或者配置成你需要指定的域名

Access-Control-Allow-Origin: www.baidu.com

js 中

js 中加载图片的时候设置 crossOrigin* 或者 anonymous 表示为希望使用跨域图片

以加载库 preload-js 为例:

this.queue = new createjs.LoadQueue(true, "", "anonymous");

如果你使用的是 image 加载的:

let img = newImage();
img.setAttribute('crossOrigin', 'anonymous'); 
img.src = images[i].url;

结束

配置完这两步就已经解决了上述问题。

才怪

如果你觉得这样就完了那就太简单了。
下面要来一些不一样的。 trollface

如果现在图片跨域了,但是你还是想绘制到 canvas 上怎么办呢?

也有办法,但你要注意几点: 👀

  • 图片CDN中存在
  • 无网络字体使用
  • 不需要能将 canvas 转为图片数据

如果你的项目能接受上面的条件,那么方法来了:

要先从跨域原因说起

请求类型 img, xhr 的请求时的区别

img 指的是 png, jpg, gif 等

img: 请求允许跨域,不受浏览器同源策略的影响
xhr: 默认不允许跨域,受浏览器跨域限制

图片跨域

知道了当加载类型为 img 时~其实图片是不存在跨域情况的。那么之所以你请求的图片跨域了,其主要原因是使用了 xhr 加载的图片。

image.png

图片是服务器已经配置过 Access-Control-Allow-Origin 的,所以加载成功了

那怎么样改成 img 类型呢?

继续绘制

let img = new Image();  
img.setAttribute('crossOrigin', 'anonymous');  
img.src = "url.png";  
img.onload = ()=>{};  

这就是 img 类型的加载事例。

很多图片加载库默认会使用:xhr 方式加载

同样以 preload-js 为例来使用 img 类型:

this.queue = new createjs.LoadQueue(true, "", "anonymous");  
this.queue.useXHR = false; // 设置不使用 `xhr` 加载  

这个时候你在去看控制台(network)时就会发现,图片全是 png,jpg,gif 了,而且 Access-Control-Allow-Origin 此类的报错也没有了。

结果

细心的你可能已经看到:上面问题描述里第二条中的图片 canvas 里就已经把图片画出来了。

简单几步 canvas 中继续绘图显示就没有问题了~

但最后还是要提醒一下,

  1. 网络字体没办法解决,只是用最上方的解决方法
  2. canvas 不能转为图片数据 toDataURL 不能调用

真的结束

到这里就真的是结束了。 trollface


标题:canvas 图片跨域问题
作者:K
地址:https://pala.icu/articles/2019/12/25/1577252188577.html