"Unable to get image data from canvas because the canvas has been tainted by cross-origin data"问题产生原因及解决办法

一、问题描述:

在支持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上对该问题的一个回答: 

翻译如下:为了阻止欺骗,浏览器会追踪 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。

 

 

 

posted @ 2012-06-27 16:24  阿洒  阅读(18147)  评论(2编辑  收藏  举报