首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何修复getImageData()错误画布被跨域数据污染?

如何修复getImageData()错误画布被跨域数据污染?
EN

Stack Overflow用户
提问于 2014-02-28 22:22:55
回答 13查看 180K关注 0票数 151

我的代码在我的本地主机上工作得很好,但在站点上却不能工作。

对于这一行.getImageData(x,y,1,1).data,我从控制台得到了这个错误

代码语言:javascript
复制
Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. 

我的部分代码:

代码语言:javascript
复制
jQuery.Event.prototype.rgb=function(){
        var x =  this.offsetX || (this.pageX - $(this.target).offset().left),y =  this.offsetY || (this.pageY - $(this.target).offset().top);
        if (this.target.nodeName!=="CANVAS")return null;
        return this.target.getContext('2d').getImageData(x,y,1,1).data;
    }

注意:我的图像url (源)来自子域url

EN

回答 13

Stack Overflow用户

发布于 2015-01-08 20:23:52

正如其他人所说的那样,你从一个跨来源的域中加载,这是在“污染”画布。

https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image

但是,您可以通过简单地设置以下内容来防止这种情况:

代码语言:javascript
复制
img.crossOrigin = "Anonymous";

只有当远程服务器适当地设置以下标头时,这才能起作用:

代码语言:javascript
复制
Access-Control-Allow-Origin "*"

使用“直接链接”选项时的Dropbox file chooser就是一个很好的例子。我在oddprints.com上使用它将来自远程dropbox图像url的图像挂到我的画布中,然后将图像数据提交回我的服务器。全部在javascript中

票数 141
EN

Stack Overflow用户

发布于 2015-10-15 05:21:23

我发现我必须使用.setAttribute('crossOrigin', ''),并且必须在URL的查询字符串上附加一个时间戳,以避免缺少Access-Control-Allow-Origin头的304响应。

这给了我

代码语言:javascript
复制
var url = 'http://lorempixel.com/g/400/200/';
var imgObj = new Image();
imgObj.src = url + '?' + new Date().getTime();
imgObj.setAttribute('crossOrigin', '');
票数 51
EN

Stack Overflow用户

发布于 2014-04-23 13:36:23

您不能直接从另一个服务器将图像绘制到画布中,然后使用getImageData。这是一个安全问题,画布将被认为是“受污染的”。

使用PHP将图像的副本保存到服务器上,然后加载新图像,对您来说是否可行?例如,您可以将URL发送到PHP脚本并将其保存到服务器,然后将新文件名返回给javascript,如下所示:

代码语言:javascript
复制
<?php //The name of this file in this example is imgdata.php

  $url=$_GET['url'];

  // prevent hackers from uploading PHP scripts and pwning your system
  if(!@is_array(getimagesize($url))){
    echo "path/to/placeholderImage.png";
    exit("wrong file type.");
  }

  $img = file_get_contents($url);

  $fn = substr(strrchr($url, "/"), 1);
  file_put_contents($fn,$img);
  echo $fn;

?>

您可以将PHP脚本与一些ajax javascript一起使用,如下所示:

代码语言:javascript
复制
xi=new XMLHttpRequest();
xi.open("GET","imgdata.php?url="+yourImageURL,true);
xi.send();

xi.onreadystatechange=function() {
  if(xi.readyState==4 && xi.status==200) {
    img=new Image;
    img.onload=function(){ 
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    }
    img.src=xi.responseText;
  }
}

如果在那之后在画布上使用getImageData,它会工作得很好。

或者,如果您不想保存整个图像,则可以将x&y坐标传递给PHP脚本,并计算该侧像素的RGBA值。我认为在PHP中有很好的库可以做这样的图像处理。

如果你想使用这种方法,如果你需要帮助来实现它,请让我知道。

编辑-1: peeps指出php脚本已经暴露,允许互联网恶意使用它。有一百万种方法来处理这个问题,最简单的方法之一就是对URL进行模糊处理……我认为安全的php实践应该有一个单独的谷歌。

edit-2:根据流行的需求,我添加了一个检查,以确保它是一个图像而不是一个php脚本(来自:PHP check if file is an image)。

票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22097747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档