canvas.todataurl跨域,canvas.todataurl()
一、首先,图片服务器需要配置Access-Control-Allow-Origin
一般团队会有专用域名放置静态资源,比如腾讯是gtimg.com,百度是bdimg.com;或者很多团队使用腾讯云或者阿里云的服务。
但是,主页的域名往往是不同的。当需要对画布图像进行getImageData()或toDataURL()操作时,跨域问题就出来了,而且跨域问题不止一层。
首先,在第一步中,图像服务器需要配置访问控制允许来源信息,例如:
如果PHP添加了响应头信息,通配符*表示允许任何域名:
header( Access-Control-Allow-Origin:*);或者指定域名:
header( Access-Control-Allow-Origin:www . Zhang xinxu . com );此时,Chrome浏览器中不会出现与Access-Control-Allow-Origin相关的错误信息,但会出现其他跨域错误信息。
二、canvas图片getImageData cross-origin跨域问题
对于跨域图片,只要能在网页中正常显示,就可以使用canvas的drawImage() API进行绘制。但如果想更进一步,通过getImageData()方法得到图片完整的像素信息,很可能会出错。
例如,使用以下代码在github上获取您的头像图片信息:
var canvas=document . createelement( canvas );var context=canvas . get context( 2d );var img=new Image();img . onload=function(){ context . draw image(this,0,0);context.getImageData(0,0,this.width,this . height);};img . src= https://avatar S3 . githubusercontent . com/u/496048?s=120v=4 ;;因此,Chrome浏览器下会显示以下错误:
未捕获的DOMException:无法对“CanvasRenderingContext2D”执行“getImageData”:画布已被跨原点数据污染。
Firefox错误是:
SecurityError:操作不安全。
如果使用canvas.toDataURL()方法,它将报告:
未能对“HTMLCanvasElement”执行“toDataURL”:受感染的canvased可能无法导出
其实原因都一样,跨域导致的。
有什么办法解决这个问题吗?
可以试试crossOrigin属性。
三、HTML crossOrigin属性解决资源跨域问题
在HTML5中,一些元素提供了支持CORS(跨源资源共享)的属性。这些元素包括img、视频、剧本等。提供的属性名是crossOrigin属性。
因此,上述跨域问题可以这样处理:
var canvas=document . createelement( canvas );var context=canvas . get context( 2d );var img=new Image();img . cross origin=“”;img . onload=function(){ context . draw image(this,0,0);context.getImageData(0,0,this.width,this . height);};img . src= https://avatar S3 . githubusercontent . com/u/496048?s=120v=4 ;;只需添加一个img.crossOrigin= ,虽然这里的JS代码设置了空字符串,但是有效属性值是匿名的。
CrossOrigin可以有以下两个值:
关键字定义匿名元素的跨域资源请求不需要凭证标志设置。use-credentials元素的跨域资源请求需要凭据标志设置,这意味着请求需要提供凭据。
其中,只要crossOrigin的属性值不是use-credentials,就会全部解析为匿名,包括空字符串,包括 abc 这样的字符。
例如:
img.crossOrigin= abcconsole . log(img . cross origin);//结果是“匿名”
还有一点需要注意的是,虽然没有crossOrigin属性,并且设置crossOrigin=use-credentials 会默认报告跨域错误,但本质上是不同的,两者有很大的区别。
crossOrigin兼容性
IE11 (IE Edge)、Safari、Chrome、Firefox浏览器都支持。IE9和IE10会报告SecurityError,如下图截图所示:
四、crossOrigin属性为什么可以解决资源跨域问题?
CrossOrigin=匿名。相比告诉对方服务器,不需要带任何非匿名信息。如cookie,因此,目前的浏览器肯定是安全的。
就像你要去别人家拿件衣服。crossOrigin=anonymous是相对于告诉对方,我只要衣服,不要别的。如果不说,可能对方在衣服里放了窃听器什么的,就不安全了,浏览器也会阻止。
五、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做任何你想做的事情。//.密码.//使用完图片记得释放内存URL . revokeobjecturl(URL);};img.src=url};xhr.open(GET ,url,true);xhr.responseType= blobxhr . send();这种方法不仅在IE10浏览器中可以,在原本支持crossOrigin的浏览器中也可以支持。
只需再接受一个ajax请求。没事的!
根据,根据惯例,在IE浏览器下,如果请求的图片太大,比如几千个像素,图片就会加载失败,我猜超过了blob大小限制。
六、结束语
最近在工作中学习了一点经验,希望能帮助到遇到类似问题的朋友。也希望大家能支持我。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。