详解怎样处理canvas照片getImageData,toDataURL跨域难题

2021-02-23 03:12 jianzhan

1、最先,照片服务器必须配备Access-Control-Allow-Origin

1般精英团队都会有1个专业网站域名置放静态数据資源,比如腾迅是gtimg.com,百度搜索是bdimg.com;或许多精英团队应用的是腾迅云或阿里巴巴云的服务。

而首页面所属网站域名常常不1样,当必须必须对canvas照片开展getImageData()或toDataURL()实际操作的情况下,跨域难题就出来了,并且跨域难题还不止1层。

最先,第1步,照片服务器必须配备Access-Control-Allow-Origin信息内容,比如:

如PHP加上回应头信息内容,*通配符表明容许随意网站域名:

header("Access-Control-Allow-Origin: *");

或特定网站域名:

header("Access-Control-Allow-Origin: www.zhangxinxu.com");

此时,Chrome访问器就不容易有Access-Control-Allow-Origin有关的不正确信息内容了,可是,还会有别的的跨域不正确信息内容。

2、canvas照片getImageData cross-origin跨域难题

针对跨域的照片,要是可以在网页页面中一切正常显示信息出来,便可以应用canvas的drawImage() API绘图出来。可是假如你想更进1步,根据getImageData()方式获得照片的详细的像素信息内容,则大多数会错误。

举例来讲,应用下面编码获得github上的自身头像照片信息内容:

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var img = new Image();
img.onload = function () {
    context.drawImage(this, 0, 0);
    context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

結果在Chrome访问器下显示信息以下不正确:

Uncaught DOMException: Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data.

Firefox访问器不正确为:

SecurityError: The operation is insecure.

假如应用的是canvas.toDataURL()方式,则会报:

Failed to execute ‘toDataURL’ on ’HTMLCanvasElement’: Tainted canvased may not be exported

缘故实际上全是1样的,跨域致使。

那有木有甚么方法能够处理这个难题呢?

能够试试crossOrigin特性。

3、HTML crossOrigin特性处理資源跨域难题

在HTML5中,一些元素出示了适用CORS(Cross-Origin Resource Sharing)(跨域資源共享资源)的特性,这些元素包含<img>,<video>,<script>等,而出示的特性名便是crossOrigin特性。

因而,上面的跨域难题能够这么解决:

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var img = new Image();
img.crossOrigin = '';
img.onload = function () {
    context.drawImage(this, 0, 0);
    context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

提升1个img.crossOrigin = ''便可,尽管JS编码这里设定的是空标识符串,具体上起功效的特性值是anonymous。

crossOrigin能够有下面两个值:

重要字 释义 anonymous 元素的跨域資源恳求不必须凭据标示设定。 use-credentials 元素的跨域資源恳求必须凭据标示设定,代表着该恳求必须出示凭据。

在其中,要是crossOrigin的特性值并不是use-credentials,所有都会分析为anonymous,包含空标识符串,包含相近'abc'这样的标识符。

比如:

img.crossOrigin = 'abc';
console.log(img.crossOrigin);    // 結果是'anonymous'

此外也有1点必须留意,那便是尽管沒有crossOrigin特性,和设定crossOrigin="use-credentials"在默认设置状况下都会报跨域错误,可是特性上却不1样,二者有较大差别。

crossOrigin适配性

IE11+(IE Edge),Safari,Chrome,Firefox访问器均适用,IE9和IE10会报SecurityError安全性不正确,以下截图:

4、crossOrigin特性为何能够处理資源跨域难题?

crossOrigin=anonymous相对告知对方服务器,你不必须带任何非密名信息内容过来。比如cookie,因而,当今访问器毫无疑问是安全性的。

就如同你要去他人家里拿1件衣服,crossOrigin=anonymous相对告知对方,我要是衣服,别的都不必。假如不说,将会对方在衣服里放个监听器甚么的,就躁动不安全了,访问器就会阻拦。

5、IE10访问器不适用crossOrigin如何办?

大家恳求照片的情况下,并不是立即根据new Image(),而是依靠ajax和URL.createObjectURL()方式曲线图救国。

编码以下:

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    var url = URL.createObjectURL(this.response);
    var img = new Image();
    img.onload = function () {
        // 此时你便可以应用canvas对img肆无忌惮了
        // ... code ...
        // 照片用完续篇得释放出来运行内存
        URL.revokeObjectURL(url);
    };
    img.src = url;
};
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();

此方式不但IE10访问器OK,本来适用crossOrigin的各位访问器也是适用的。

也就多走1个ajax恳求,还能够!

依据,依据实践活动发现,在IE访问器下,假如恳求的照片过大,几千像素那种,照片会载入不成功,我猜是超出了blob规格限定。

6、完毕语

近期工作中初中到的1点小工作经验,期待能够帮到遇到相近难题的小伙子伴。也期待大伙儿多多适用脚本制作之家。