如何修复getImageData()而导致的帆布已经被跨域数据污点?如何修复getImageData

2019-05-09 01:13发布

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

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

Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. 

我的代码部分:

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(SRC)是从一个子域网址

Answer 1:

正如其他人说你是从跨起源域加载“玷污”的画布。

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

但是,你可以通过简单的设置,以防止这种情况:

img.crossOrigin = "Anonymous";

这只有在远程服务器适当设置下列的头工作原理:

Access-Control-Allow-Origin "*"

在Dropbox的文件选择使用“直接连接”选项时,就是一个很好的例子。 我用它在oddprints.com从远程Dropbox的图像URL胡佛了图片,进入我的画布,然后将图像数据提交回我的服务器。 所有在javascript



Answer 2:

我发现,我不得不使用.setAttribute('crossOrigin', '')不得不时间戳追加到URL的查询字符串,以避免304响应缺少Access-Control-Allow-Origin头。

这给了我

var url = 'http://lorempixel.com/g/400/200/';
var imgObj = new Image();
imgObj.src = url + '?' + new Date().getTime();
imgObj.setAttribute('crossOrigin', '');


Answer 3:

你将无法直接从另一台服务器上绘制图像到画布上,然后使用getImageData 。 这是一个安全问题,画布将被视为“污点”。

将它的工作让你使用PHP图像的副本保存到您的服务器,然后只加载新的形象? 例如,您可以将网址发送到PHP脚本,并将其保存到服务器,然后将新的文件名返回到您的JavaScript这样的:

<?php //The name of this file in this example is imgdata.php

  $url=$_GET['url'];
  $img = file_get_contents($url);
  $fn = substr(strrchr($url, "/"), 1);
  file_put_contents($fn,$img);
  echo $fn;

?>

你会使用PHP脚本,像这样一些AJAX脚本:

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好的库。

如果你想用这个办法,让我知道,如果你需要帮助实现它。



Answer 4:

你的问题是,你加载外部图像,从另一个域的意思。 这将导致一个安全错误,当您尝试访问画布上下文的任何数据。



Answer 5:

你是从跨起源域加载“玷污”的画布。 看看这篇文章MDN:

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



Answer 6:

我是在看到此错误Chrome ,而我是在本地测试我的代码。 我切换到Firefox ,我没有看到任何错误更多。 也许切换到另一个浏览器是一个快速解决方案。

如果您使用的是第一次的答案给出的解决方案,那么请确保您添加img.crossOrigin = "Anonymous"; 刚过声明的img变量(如: var img = new Image(); )。



Answer 7:

马特烧伤在说他的回答 ,您可能需要哪里出了问题图像托管服务器上启用CORS。

如果服务器是Apache的,这可以通过添加下面的代码片段(从做在这里 ),要么你的虚拟主机配置或.htaccess文件:

<IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
        <FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
            SetEnvIf Origin ":" IS_CORS
            Header set Access-Control-Allow-Origin "*" env=IS_CORS
        </FilesMatch>
    </IfModule>
</IfModule>

...如果将其添加到虚拟主机,你可能需要重新加载Apache的配置太(如sudo service apache2 reload如果Apache的Linux服务器上运行)



Answer 8:

当工作在本地添加一台服务器

当地的工作时,我有一个类似的问题。 您的网址将是路径到本地文件,例如文件:///Users/PeterP/Desktop/folder/index.html。

请注意,我在MAC上。

我得到了这一轮的全球安装HTTP服务器。 https://www.npmjs.com/package/http-server

脚步:

  1. 全球安装: npm install http-server -g
  2. 运行服务器: http-server ~/Desktop/folder/

PS:我假设您已经安装节点,否则你不会得到很远的运行NPM命令。



Answer 9:

我今天达到了同样的问题,并通过代码如下解决它。

HTML代码:

<div style='display: none'>
  <img id='img' src='img/iak.png' width='600' height='400' />
</div>
<canvas id='iak'>broswer don't support canvas</canvas>

JS代码:

var canvas = document.getElementById('iak')
var iakImg = document.getElementById('img')
var ctx = canvas.getContext('2d')
var image = new Image()
image.src=iakImg.src
image.onload = function () {
   ctx.drawImage(image,0,0)
   var data = ctx.getImageData(0,0,600,400)
}

代码像上面,并且不存在跨域问题。



Answer 10:

我有同样的问题,对我来说通过简单地串联工作https:${image.getAttribute('src')}



文章来源: How to fix getImageData() error The canvas has been tainted by cross-origin data?