2010-03-05 89 views
86

我沒有得到足夠的睡眠或什麼?這下面的代碼爲什麼canvas.toDataURL()會引發安全異常?

var frame=document.getElementById("viewer"); 
frame.width=100; 
frame.height=100; 

var ctx=frame.getContext("2d"); 
var img=new Image(); 
img.src="http://www.ansearch.com/images/interface/item/small/image.png" 

img.onload=function() { 
    // draw image 
    ctx.drawImage(img, 0, 0) 

    // Here's where the error happens: 
    window.open(frame.toDataURL("image/png")); 
} 

引發此錯誤:

SECURITY_ERR: DOM Exception 18 

沒有辦法,這不應該工作!任何人都可以解釋這一點嗎?

+0

請參閱此處以獲取解決方案:[如何使用canvas.toDataURL()在Adobe AIR中獲取圖像的base64?](http://stackoverflow.com/q/3672332) – 2013-07-09 23:21:36

+2

該解決方案似乎對於不使用Adobe AIR的用戶。 – ObscureRobot 2013-08-16 22:53:19

回答

67

specs它說:

Whenever the toDataURL() method of a canvas element whose origin-clean flag is set to false is called, the method must raise a SECURITY_ERR exception.

如果圖像是從另一臺服務器來我不認爲你可以使用toDataURL()

+0

那裏是 – 2010-03-05 22:28:17

+0

非常感謝!像Mike R.我無法想象這將如何與安全相關! :) – pop850 2010-03-05 22:36:55

+6

如果攻擊者能夠猜出您在私人站點中擁有的圖片的名稱,他將能夠通過在畫布上繪畫並將新圖像發送到他的網站來獲取其副本。從我的觀點來看,主要的限制是避免繪製另一個站點的內容,但是安全性太複雜,因爲攻擊者可能在任何意外站點找到漏洞。 – AlfonsoML 2010-03-05 23:46:30

1

你不能把空格您的帳號

更新

我的猜測是,圖像是不同的服務器,你要執行腳本比。當我在自己的網頁上運行它時,我能夠重現您的錯誤,但是當我使用託管在同一個域上的圖像時,它運行良好。所以它與安全有關 - 將圖像放在您的網站上。任何人都知道爲什麼會這樣?

+0

我改變了這一點,並進行了測試,但得到了相同的錯誤... – pop850 2010-03-05 22:05:38

+0

@ pop850:請參閱編輯 – Matchu 2010-03-05 22:34:05

13

似乎有一種方法,以防止,如果圖​​像託管能夠爲圖像資源和瀏覽器提供以下HTTP頭支持CORS:

access-control-allow-origin: * 
access-control-allow-credentials: true

在此聲明:http://www.w3.org/TR/cors/#use-cases

+1

access-control-allow-credentials:true將不適用於access-control-allow-origin:*。前者設置後,後者應該有一個原始值,而不是來自https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS – 2013-06-13 13:59:32

16

如果映像駐留在設置訪問控制允許源或訪問控制允許證書的主機上,則可以使用跨源資源共享(CORS)。 See here (the crossorigin attribute) for more details.

您的其他選項是讓您的服務器擁有一個端點來提取和提供圖像。 (如http://your_host/endpoint?url=URL) 該方法的缺點是延遲和理論上不必要的提取。

如果有更多的替代解決方案,我會有興趣聽到它們。

+0

的通配符值嗨,我這樣做了,我有Access- Control-Allow-Origin:*上的圖像,我有crossorigin ='匿名',然後我畫在畫布上的圖像,然後我打電話給DataUrl,我仍然得到SECURITY_ERR:DOM例外18 – skrat 2012-07-11 14:45:16

+0

好的,使用setAttribute img.crossorigin – skrat 2012-07-11 15:33:54

17

上的圖像對象設置跨原產地屬性爲我工作(我使用fabricjs)

var c = document.createElement("img"); 
    c.onload=function(){ 
     // add the image to canvas or whatnot 
     c=c.onload=null 
    }; 
    c.setAttribute('crossOrigin','anonymous'); 
    c.src='http://google.com/cat.png'; 

對於使用fabricjs,這裏是如何修補Image.fromUrl

// patch fabric for cross domain image jazz 
fabric.Image.fromURL=function(d,f,e){ 
    var c=fabric.document.createElement("img"); 
    c.onload=function(){ 
     if(f){f(new fabric.Image(c,e))} 
     c=c.onload=null 
    }; 
    c.setAttribute('crossOrigin','anonymous'); 
    c.src=d; 
}; 
+0

謝謝,它適用於我在Chrome。我不使用fabric.js – Philip007 2013-11-02 06:44:27

+0

我使用fabricjs,但無法解決它。你如何用這個代碼來做到這一點?函數wtd_load_bg_image(img_url) if(img_url) var bg_img = new Image(); bg_img.onload =函數() { canvasObj.setBackgroundImage(bg_img.src,canvasObj.renderAll.bind(canvasObj),{ originX: '左', originY: '頂部', 左:0, 頂:0 }); }; bg_img.src = img_url; } } – HOY 2017-03-28 23:40:03

+0

也適用於Firefox。 – vanowm 2017-09-01 02:53:11

2

我有同樣的問題和所有的圖像託管在同一個域...所以,如果有人有同樣的問題,這裏是我如何解決:

我有兩個按鈕:一個生成畫布和另一個從畫布生成圖像。它只對我有效,對不起,我不知道爲什麼,當我在第一個按鈕上寫下所有代碼時。所以當我點擊它的同時生成畫布和圖像...

當代碼在不同的功能上時,我總是有這個安全問題...=/

0

如果您只是在畫布上繪製一些圖像,請確保您正在加載來自同一個域的圖像。

www.example.com是不同的,以example.com

因此,請確保您的圖片,你在地址欄中有URL是相同的,WWW或不是。

1

我能使其工作使用這樣的:創建一個<img>元素時,你的源服務器上

寫上您的.htaccess的第一線

Header add Access-Control-Allow-Origin "*" 

然後,做如下:

// jQuery 
var img = $('<img src="http://your_server/img.png" crossOrigin="anonymous">')[0] 

// or pure 
var img = document.createElement('img'); 
img.src='http://your_server/img.png'; 
img.setAttribute('crossOrigin','anonymous'); 
2

最後我找到了解決方案。只需要添加crossOrigin作爲第三PARAM在fromURL FUNC

fabric.Image.fromURL(imageUrl, function (image) { 
      //your logic 
    }, { crossOrigin: "Anonymous" }); 
+0

真的幫我用Fabric JS,謝謝! – hcabral 2018-01-16 22:11:36

0

我使用fabric.js並可以通過使用toDatalessJSON代替toDataURL的解決此問題:

canvas.toDatalessJSON({ format: 'jpeg' }).objects[0].src 

編輯:沒關係。這導致只將背景圖像導出爲JPG,而不在頂層繪製,因此畢竟沒有完全有用。

相關問題