canvas.todataurl跨域,canvas.todataurl()

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: