0

我几乎完成了一个基于 Javascript/HTML5 的游戏,我一直在通过使用 Chrome 打开本地文件系统上的 HTML 页面来测试它(我没有在任何地方上传任何东西)。我正在使用 Chrome 的file://协议来执行此操作。但是我遇到了一个问题……在游戏开始时,我会显示几秒钟的图像,然后再进入菜单屏幕。我通过抓取画布的像素数据来暂停游戏,显示它,然后在整个物体上绘制一个半透明的矩形,用十字准线作为自定义指针。但是,Chrome 给我带来了 DOM 安全异常 18 的麻烦:"Unable to get image data from canvas because the canvas has been tainted by cross-origin data."

所以我在网上做了一些研究,结果发现这是因为 Chrome 看到图像是从本地文件系统中抓取的,并认为这是一个安全错误。使用这个问题作为参考,我尝试对跨域资源共享进行一些研究,但很快就迷路了。http://我认为使用并localhost像问题回答者建议的那样简单地打开测试 HTML 文件会容易得多。但我也不知道该怎么做。

我真的很想用 Chrome 继续测试我的游戏(通过它访问的开发者工具Ctrl-Shift-I被证明是无价的),所以我想有三个解决方案:要么弄清楚 CORS 是什么以及如何使用它,要么学习如何打开使用 的本地文件http://,或者以某种方式将我的图像数据硬编码为我的 JavaScript 脚本文件中的变量(如 C 中的 XPM 文件)。我不知道如何做前两个,我试图避免第三个。

4

2 回答 2

2

是的,可能是时候下载本地 Web 服务器或注册托管服务器了。

但是,如果您想在没有服务器的情况下继续测试,您可以注册一个免费的 dropbox.com 帐户并在那里托管您的图像。

Dropbox 允许使用 CORS 友好的 crossOrigin=”anonymous” 访问图像。

那么 CORS 在 Chrome 和 Mozilla 上是没有问题的。但是,IE 仍然对 CORS 不友好——加油 IE :(

这是从 Dropbox(Chrome 和 Mozilla,而不是 IE)加载没有 CORS 问题的图像的方法。

“秘密”是在设置 image.src 之前设置 image.crossOrigin=”anonymous”:

    var externalImage2=document.createElement("img");
    externalImage2.onload=function(){
        canvas.width=externalImage2.width;
        canvas.height=externalImage2.height;
        ctx.drawImage(externalImage2,0,0);
        // use getImageData to replace blue with yellow
        var imageData=recolorImage(externalImage2,0,0,255,255,255,0);
        // put the altered data back on the canvas  
        // this will FAIL on a CORS violation
        ctxAnonymous.putImageData(imageData,0,0);    
    }
    externalImage2.crossOrigin = "Anonymous";
    externalImage2.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";

这是代码和小提琴:http: //jsfiddle.net/m1erickson/YdzHT/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var canvasCORS=document.getElementById("canvasCORS");
    var ctxCORS=canvasCORS.getContext("2d");
    var canvasAnonymous=document.getElementById("canvasAnonymous");
    var ctxAnonymous=canvasAnonymous.getContext("2d");

    // Using image WITHOUT crossOrigin=anonymous
    // Fails in all browsers
    var externalImage1=new Image();
    externalImage1.onload=function(){
        canvas.width=externalImage1.width;
        canvas.height=externalImage1.height;
        ctx.drawImage(externalImage1,0,0);
        // use getImageData to replace blue with yellow
        var imageData=recolorImage(externalImage1,0,0,255,255,255,0);
        // put the altered data back on the canvas  
        // this will FAIL on a CORS violation
        ctxCORS.putImageData(imageData,0,0);    
    }
    externalImage1.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";

    // Using image WITH crossOrigin=anonymous
    // Succeeds in Chrome+Mozilla, Still fails in IE
    var externalImage2=new Image();
    externalImage2.onload=function(){
        canvas.width=externalImage2.width;
        canvas.height=externalImage2.height;
        ctx.drawImage(externalImage2,0,0);
        // use getImageData to replace blue with yellow
        var imageData=recolorImage(externalImage2,0,0,255,255,255,0);
        // put the altered data back on the canvas  
        // this will FAIL on a CORS violation
        ctxAnonymous.putImageData(imageData,0,0);    
    }
    externalImage2.crossOrigin = "Anonymous";
    externalImage2.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";


    function recolorImage(img,oldRed,oldGreen,oldBlue,newRed,newGreen,newBlue){
        var c = document.createElement('canvas');
        var ctx=c.getContext("2d");
        var w = img.width;
        var h = img.height;
        c.width = w;
        c.height = h;

        // draw the image on the temporary canvas
        ctx.drawImage(img, 0, 0, w, h);

        // pull the entire image into an array of pixel data
        var imageData = ctx.getImageData(0, 0, w, h);

        // examine every pixel, 
        // change any old rgb to the new-rgb
        for (var i=0;i<imageData.data.length;i+=4)
          {
              // is this pixel the old rgb?
              if(imageData.data[i]==oldRed &&
                 imageData.data[i+1]==oldGreen &&
                 imageData.data[i+2]==oldBlue
              ){
                  // change to your new rgb
                  imageData.data[i]=newRed;
                  imageData.data[i+1]=newGreen;
                  imageData.data[i+2]=newBlue;
              }
          }
        return(imageData);
    }


}); // end $(function(){});
</script>

</head>

<body>
    <p>Original external image</p>
    <canvas id="canvas" width=140 height=140></canvas>
    <p>.getImageData with .crossOrigin='anonymous'
    <p>[Succeeds in Chrome+Mozilla, still fails in IE]</p>
    <canvas id="canvasAnonymous" width=140 height=140></canvas>
    <p>.getImageData without .crossOrigin='anonymous'
    <p>[Fails on all browsers]</p>
    <canvas id="canvasCORS" width=140 height=140></canvas>
</body>
</html>
于 2013-06-17T04:11:14.560 回答
1

由于您发现的原因,使用本地文件系统进行开发通常不是一个好主意。要使用该localhost选项,您需要在 PC 上安装 Web 服务器。谷歌搜索 WAMP 包(Windows、Apache、MySQL、PHP),它可以为您提供所需的一切。

不幸的是,CORS 仅适用于您拥有 Web 服务器的情况!

[编辑] 显然,您可以从wampserver.com获得 WAMP 服务器!

于 2013-06-17T03:16:09.730 回答