Поддержка браузера CORS для манипулирования загруженными изображениями в нескольких доменах - PullRequest
25 голосов
/ 20 августа 2011

ВОПРОС: Какие версии браузера поддерживают заголовки CORS (Cross-Origin Resource Sharing) для междоменного домена Изображения , используемые в Canvas?

CORS может применяться к обоим кросс-кроссамДомен XMLHttpRequests и запросы изображений.Этот вопрос о запросах изображений Мой обычный переход на совместимость версий браузера http://caniuse.com/cors неясен по этому вопросу, и поиск в Google не дает хороших результатов.

Я нашел недавнийБлог по разработке Chrome, подразумевающий, что поддержка CORS широко распространена в современных браузерах, но может прекратиться из-за проблем безопасности WebGL.
http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html

Подробнее о CORS:

Мы рассматриваем возможность использования canvas & CORS с междоменными запросами изображений, как описано в рабочем проекте W3C http://www.w3.org/TR/cors/#use-cases. CORS используется html canvas, чтобы разрешить использование междоменных ресурсов способом, аналогичным способу flashиспользует crossdomain.xml.По сути, мы хотим читать / редактировать пиксели данных изображения и не хотим использовать один и тот же исходный прокси-сервер.

Обычно, если изображения загружаются между доменами и используются с холстом html, доступ к пикселям с помощью таких функций, как canvas.toDataURL (), приведет к ошибке безопасности.Однако, если сервер, доставляющий изображение, добавляет такой заголовок, следует разрешить использование междоменного домена.

access-control-allow-origin: *

Браузеры, которые нас больше всего интересуют:

Мымы планируем обойти проблему отсутствия поддержки IE в Canvas с использованием Flash, поэтому для настольных браузеров с проблемой CORS мы тоже можем это сделать, но для мобильных устройств Flash это не вариант, и использование прокси-сервера для выполнения запросов из одного источника не являетсявариант в нашем случае использования.Итак, меня особенно интересует поддержка браузерами Andriod, Iphone, IPAD для CORS.

Ответы [ 3 ]

19 голосов
/ 21 августа 2011

Результаты теста : Плохие новости, похоже, работает только в Chrome.Все другие браузеры (включая Android Mobile) выдают такую ​​ошибку:

Failed: DOM Exception: SECURITY_ERR (18)

Мобильные устройства Я тестировал Android (ядро Samsung Galaxy версии 2.6.32.9), Iphone и IPAD V1не удалось во всех трех.

Вы можете протестировать свое собственное мобильное устройство с этим URL: http://maplarge.com/CrossOriginImageTest.html

Сценарий тестирования:

  <!DOCTYPE html>
<html>
<head>
<title>Canvas Cross Origin Image Test: Testing for Canvas Cross Domain Image CORS Support</title>
<script type="text/javascript">
    function initialize() {

        //will fail here if no canvas support
        try {
            var can = document.getElementById('mycanvas');
            var ctx = can.getContext('2d');
            var img = new Image();
            img.crossOrigin = '';
            //domain needs to be different from html page domain to test cross origin security
            img.src = 'http://lobbydata.com/Content/images/bg_price2.gif';
        } catch (ex) {
            document.getElementById("results").innerHTML = "<span style='color:Red;'>Failed: " + ex.Message + "</span>";
        }

        //will fail here if security error
        img.onload = function () {
            try {
                var start = new Date().getTime();
                can.width = img.width;
                can.height = img.height;
                ctx.drawImage(img, 0, 0, img.width, img.height);
                var url = can.toDataURL(); // if read succeeds, canvas isn't dirty.
                //get pixels
                var imgd = ctx.getImageData(0, 0, img.width, img.width);
                var pix = imgd.data;
                var len = pix.length;
                var argb = []; //pixels as int
                for (var i = 0; i < len; i += 4) {
                    argb.push((pix[i + 3] << 24) + (pix[i] << 16) + (pix[i + 1] << 8) + pix[i + 2]);
                }
                var end = new Date().getTime();
                var time = end - start;
                document.getElementById("results").innerHTML = "<span style='color:Green;'>" +
                "Success: Your browser supports CORS for cross domain images in Canvas <br>"+
                "Read " + argb.length+ " pixels in "+ time+"ms</span>";
            } catch (ex) {
                document.getElementById("results").innerHTML = "<span style='color:Red;'>Failed: " + ex + "</span>";
            }

        }

    }
</script>
</head>
<body onload="initialize()">
<h2>Canvas Cross Origin Image Test: Testing for Canvas Cross Domain Image CORS Support</h2>
<h2><a href="http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html">What is CORS Image Security?</a></h2>
<h1 id="results" style="color:Orange;">Testing...</h1>
<canvas id="mycanvas"></canvas>
<br />
<a href="/Example/List">More Examples</a>
</body>
</html>
3 голосов
/ 28 декабря 2012

Я только что проверил это на своем iPhone под управлением iOS 6 в Safari и в Chrome, и ваша тестовая страница прошла тест. Я бы опубликовал это как комментарий, но у меня нет возможности опубликовать комментарий к вашему ответу.

1 голос
/ 08 января 2013

Вы можете использовать php, чтобы получить все, что вы хотите без CROS, рабочий пример ниже:

<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
function a(x){
alert(x);
var img = new Image();
            img.onload = function()
            {
            var canvas = document.createElement("canvas");
            canvas.width = img.width;
            canvas.height = img.height;
            var context = canvas.getContext("2d");
            context.fillStyle = "#ffffff";
            context.fillRect(0,0,img.width,img.height);
            context.drawImage(img, 0, 0);
            var data = canvas.toDataURL('image/jpeg' , 0.8);
            document.write('<img src="'+data+'" />');
            };img.src = x;
}
</script>
<?php
$im = imagecreatefromjpeg('http://www.nasa.gov/images/content/711375main_grail20121205_4x3_946-710.jpg');
            ob_start();
            imagejpeg($im,NULL,100);
            $outputBuffer = ob_get_clean();
            $base64 = base64_encode($outputBuffer);
            $x= 'data:image/jpeg;base64,'.$base64;
            echo "<script>a('".$x."')</script>";
?>
...