2011-08-20 66 views
25

問題:哪些瀏覽器版本支持跨域的CORS(跨源資源共享)標頭圖片在Canvas中使用?瀏覽器Canvas CORS支持跨域加載的圖像處理

CORS可以應用於跨域XMLHttpRequests和圖像請求。這個問題是關於圖像請求我正常去瀏覽器版本兼容http://caniuse.com/cors目前尚不清楚的問題和谷歌搜索沒有產生好的結果。

我確實發現了一個最近的chrome開發博客,暗示CORS支持在現代瀏覽器中廣泛傳播,但可能因WebGL安全問題而中斷。
http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html

上CORS的更多細節:

我們正在考慮使用帆布& CORS與作爲W3C工作草案http://www.w3.org/TR/cors/#use-cases描述跨域圖像請求的可行性。 CORS被html canvas使用,以類似於flash使用crossdomain.xml的方式允許跨域資源使用。基本上,我們想要讀取/編輯圖像數據像素,我們不想使用同一個原始代理服務器。

通常情況下,如果圖像加載跨域並與html canvas一起使用,則使用像canvas.toDataURL()這樣的函數訪問像素將引發安全錯誤。但是,如果傳遞圖像的服務器添加這樣的標題,則應允許跨域使用。

access-control-allow-origin: * 

瀏覽器,我們最關心的:

我們計劃來解決IE的缺乏畫布支持使用閃光燈,所以與CORS問題的桌面瀏覽器,我們可以做到這一點爲好,但移動閃存不是一個選項,並且使用代理來使請求相同的來源不是我們用例中的選項。所以,我對Andriod,Iphone,CORS的IPAD瀏覽器支持特別感興趣。

回答

19

測試結果:壞消息,它似乎只適用於Chrome。 所有其他瀏覽器(包括Android手機)給出瞭如下的錯誤:

Failed: DOM Exception: SECURITY_ERR (18) 

移動設備我測試的Android(三星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> 
+2

我正要張貼這個問題。很高興我不是唯一一個瘋狂的人認爲這個*應該*工作。這現在在FF17中工作,但仍然不能在IE10中工作。猜猜我必須繼續使用我的請求代理。 – pseudosavant

+2

1.5年後更新:在Windows上,我只測試了IE9(失敗),Safari 5.0.5(失敗),Firefox(通行證)和Chrome(通行證) – Glenn

+0

在safari上檢查了iPad 3上的演示頁面,並且工作正常。 – metric152

3

我只是測試這在Safari和Chrome瀏覽器我的iPhone運行iOS 6並且您的測試頁通過測試。我會發布此評論作爲評論,但我沒有給你的答案發表評論的選項。

+0

好消息!我的帖子是一年半的時間,所以我很高興看到瀏覽器進步。 – Glenn

+1

我在Windows 8 - IE 10中測試過,但仍然失敗。 – bfcoder

+1

在Mac OSX 10.7.5 - Safari 6.0.2中測試通過。 – bfcoder

1

你可以使用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>"; 
?> 
+2

這看起來像一個代理服務。如果您控制託管該頁面的域並且可以添加此腳本,它應該可以工作。但是,如果你不這樣做,你就會被困在處理CORS的限制中。對於託管可嵌入窗口小部件或提供api服務的網站而言,這尤其痛苦,因爲這意味着每個想要使用畫布觸摸圖像的用戶都必須設置自己的域特定代理,如果他們想要適應不正確的瀏覽器實施CORS。由於這個問題在很多瀏覽器中都很常見,所以不能忽略。 – Glenn

+1

最重要的是獲得base64解碼圖像到畫布,因爲沒有CORS限制。而在API服務中,也有可能向客戶端提供base64解碼圖像而不是圖像URL。 – varoniic

+0

如果你的32KB以下,你甚至可以得到IE8的支持。我很好奇文本轉換膨脹和解碼​​性能。你有沒有運行任何統計數據?這傢伙建議臃腫可能相當大http://appcropolis.com/javascript-encode-images-dataurl/ – Glenn