Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data 【转】

来源:赵克立博客 分类: 前端开发 标签:js异常canvasCanvas发布时间:2016-12-09 09:13:55最后更新:2016-12-09 09:32:09浏览:7113
版权声明:
本文为博主学习过程中整理发布,如有侵权请告知
更新时间:
2016-12-09 09:32:09
温馨提示:
学无止境,技术类文章有它的时效性,请留意文章更新时间,如发现内容有误请留言指出,防止别人"踩坑",我会及时更新文章

一、问题描述:

在支持html5的浏览器中运行javascript脚本,脚本主要是操作网页上的标签canvas,出错的操作为, getImageData(img,……),

chrome 下出错信息为:"Unable to get image data from canvas because the canvas has been tainted by cross-origin data",

fireFox 下出错信息为: "Security error" code: "1000"

关键代码如下所示:

init:function(){
            var img=new Image();
            img.src="http://10.0.5.199:8080/hadoopWebGis2/jsp/map.jsp?img=0_0_0";
            var ctx=this.context3D;
            img.onload=function(){
                ctx.drawImage(img,0,0);
                var imgData=ctx.getImageData(0,0,img.width,img.height);  //出错行
                ctx.putImageData(imgData,50,50);
            };
        },


二、探索与解答

在网上搜索时发现大部分都说的是,getImageData这个函数,必须在服务器端运行,如果没有服务器环境(比如,只是一个本地的 html网页,操作本地的一张图片),就会报"Unable to get image data from canvas because the canvas has been tainted by cross-origin data"错误。

但是很明显的,我上面的示例程序是运行在一个 tomcat服务器中的,仍然报了这个错误。那么这个问题到底是怎么回事呢?

后来在stackoverflow上找到了问题的原因。(强烈推荐stackoverflow网站,这是一个非常著名的技术问答网站,涵盖的范围非常广,包括C、C++、java、web、linux等各方面。中国学生大多不喜欢看英文网页,但事实上,很多问题,中文网页看一大堆也没有办法,在很多优秀的英文网站,如stackoverflow上却能很快找到答案。)

下面是stackoverflow上对该问题的一个回答:


1481245898657826.png


翻译如下:为了阻止欺骗,浏览器会追踪 image data。当你把一个“跟canvas的域不同的”图片放到canvas上,这个canvas就成为 “tainted”(被污染的,脏的),浏览器就不让你操作该canvas 的任何像素。这对于阻止多种类型的XSS/CSRF攻击(两种典型的跨站攻击)是非常有用的。

上面的话中关键点在于红色标记出的文字“跟canvas的域不同的”, 于是我查看了我的图片请求与网页请求的地址,发现它们的域果然是不同的,

图片请求地址:http://10.0.5.199:8080/hadoopWebGis2/jsp/map.jsp?img=0_0_0

输入浏览器中的网页的地止为:http://summer1:8080/hadoopWebGis2/jsp/map3D.html

(虽然在hosts文件中配置的影射为:10.0.5.199:summer1,按理说会浏览器会自动对两者进行转换的,却不知为什么,还是识别成了不同的域。)

修改为如下后,问题解决:

图片请求地址:http://summer1:8080/hadoopWebGis2/jsp/map.jsp?img=0_0_0

输入浏览器中的网页的地止为:http://summer1:8080/hadoopWebGis2/jsp/map3D.html

-----------------或者-------------------------

图片请求地址:http://10.0.5.199:8080/hadoopWebGis2/jsp/map.jsp?img=0_0_0

输入浏览器中的网页的地止为:http://10.0.5.199:8080/hadoopWebGis2/jsp/map3D.html

---------------------------------------------------------------------------------------------------------------------------------------------------------

题外话:为什么没有服务器环境(比如,只是一个本地的 html网页,操作本地的一张图片),就会报"Unable to get image data from canvas because the canvas has been tainted by cross-origin data"错误 ?

个人理解:本地网页的域为file://,如:file:///home/summer/Desktop/test.html ,而本地图片肯定不是以file://开头的,如linux环境下的某个图片为:/home/summer/Desktop/test.png,windows环境下的某个图片为: c:\tmp\test.png。


微信号:kelicom QQ群:215861553 紧急求助须知
Win32/PHP/JS/Android/Python