【问题标题】:Why I get an Exception 18 when I try to get the image data of an Image with Access-Control-Allow-Origin: * in the response header?当我尝试在响应标头中获取带有 Access-Control-Allow-Origin: * 的图像的图像数据时,为什么会出现异常 18?
【发布时间】:2013-04-20 17:21:49
【问题描述】:

当我尝试通过 getImageData 方法获取图像的像素时,出现此错误

“无法从画布获取图像数据,因为画布已经 被跨域数据污染。未捕获的错误:SecurityError:DOM 例外 18"

图像在标题响应中具有 Access-Control-Allow-Origin: *。所以,我不明白为什么会出现这个错误。我必须做些什么来解决这个问题?

我尝试将属性 crossOrigin 添加到图像中,但这在 Safari 中不起作用。 我正在处理的代码如下。

<html>
<head>
<title>Example</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
    var img = new Image();
    img.onload = function() {
        var ctx = $('#cnv')[0].getContext('2d');
        ctx.drawImage(this, 0, 0);
        var originalImageData = ctx.getImageData(0, 0, 300, 300); // Exception 18
    };
    img.src = 'http://api.thumbr.it/1f86404a001828912f295a74b8a4d337/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebrown-eframe1/thumb.jpg';
    $('body').append(img);
</script>
</head>
<body>
<h1>Example</h1>
<img class="image" id="img-rara" src="http://api.thumbr.it/f4414f15f6d6d2639a17c6e1c025d970/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebarcelona-eframe1/thumb.jpg" />
<canvas id="cnv" width="711" height="400" />
</body>
</html>

【问题讨论】:

    标签: javascript jquery canvas cors


    【解决方案1】:

    在客户端,请务必在设置 img.src 之前设置 crossOrigin 标志

    img.crossOrigin='anonymous' 
    

    这是您的跨域访问设置为匿名的代码:

    <html>
    <head>
    <title>Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript">
        var img = new Image();
        img.onload = function() {
            var ctx = $('#cnv')[0].getContext('2d');
            ctx.drawImage(this, 0, 0);
            var originalImageData = ctx.getImageData(0, 0, 300, 300); // Exception 18
        };
    
        // allow cross-origin access
        img.crossOrigin='anonymous' 
    
        img.src = 'http://api.thumbr.it/1f86404a001828912f295a74b8a4d337/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebrown-eframe1/thumb.jpg';
        $('body').append(img);
    </script>
    </head>
    <body>
    <h1>Example</h1>
    <img class="image" id="img-rara" src="http://api.thumbr.it/f4414f15f6d6d2639a17c6e1c025d970/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebarcelona-eframe1/thumb.jpg" />
    <canvas id="cnv" width="711" height="400" />
    </body>
    </html>
    

    【讨论】:

    • crossOrigin 属性在 Chrome 和 Firefox 等浏览器中有效,但在 Safari 中无效。那么......你知道另一种获取图像数据的方法吗?谢谢!
    • 好吧,这有点骇人听闻……但是您可以将图像 url 包装在 jsonP 请求中并将其从服务器退回。由于它以 json 的形式返回,因此跨域警察忽略了它。如果您没有时间配置它,这里有一个库可以为您完成:maxnov.com/getimagedata
    【解决方案2】:

    我找到了另一种通过 XMLHttpRequest 解决这个问题的方法。此解决方案适用于 Chrome、Safari、Firefox 和 Opera,但不适用于 IE。访问此页面 http://jsperf.com/encoding-xhr-image-data/12 了解更多信息。

    <html>
    <head>
    <title>Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript">
        // See: http://jsperf.com/encoding-xhr-image-data/12
        $('body').ready(function(){
            data = getImageData(
                'http://api.thumbr.it/1f86404a001828912f295a74b8a4d337/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebrown-eframe1/thumb.jpg');
        });
        function getImageData(url) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, false);
            xhr.overrideMimeType('text/plain; charset=x-user-defined');
            xhr.send();
    
            var img = $('<img>');
            img.attr(
                'src',
                'data:image/' + getType(xhr.responseText.slice(0, 4)) + ';base64,' + getDataBase64(xhr.responseText)
            );
            img.load(function() {
                var ctx = $('#cnv')[0].getContext('2d');
                ctx.drawImage(img[0], 0, 0);
                data = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height); // Data!!
            });
        }
        function getDataBase64(data) {
            var binary = '';
            for (var i = 0; i < data.length; i+=4) {
                binary += String.fromCharCode(
                    data.charCodeAt(i+0) & 0xff,
                    data.charCodeAt(i+1) & 0xff,
                    data.charCodeAt(i+2) & 0xff,
                    data.charCodeAt(i+3) & 0xff
                );
            }
            for (i-=4; i < data.length; i+=1) {
                binary += String.fromCharCode(data.charCodeAt(i) & 0xff);
            }
            return window.btoa(binary);
        }
        function getType(data) {
            if (data.search('PNG') >= 0) {
                return 'png';
            } else if (data.search('GIF') >= 0) {
                return 'gif';
            } else {
                return 'jpeg';
            }
        }
    </script>
    </head>
    <body>
    <h1>Example</h1>
    <img class="image" id="img-rara" src="http://api.thumbr.it/f4414f15f6d6d2639a17c6e1c025d970/D-lvXHFIHpY/api.thumbr.it/static/ladies-800.png/400x400c-ebarcelona-eframe1/thumb.jpg" />
    <canvas id="cnv" width="400" height="400" />
    </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 2017-06-15
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 2021-05-30
      • 2022-11-11
      • 2019-02-07
      • 2017-01-25
      相关资源
      最近更新 更多