濮阳杆衣贸易有限公司

主頁 > 知識庫 > 詳解如何解決canvas圖片getImageData,toDataURL跨域問題

詳解如何解決canvas圖片getImageData,toDataURL跨域問題

熱門標(biāo)簽:高德地圖標(biāo)注商戶怎么標(biāo) 欣鼎電銷機(jī)器人 效果 電話機(jī)器人技術(shù) ok電銷機(jī)器人 惡搞電話機(jī)器人 智能電銷機(jī)器人被禁用了么 地圖標(biāo)注軟件打印出來 如何查看地圖標(biāo)注 黃石ai電銷機(jī)器人呼叫中心

一、首先,圖片服務(wù)器需要配置Access-Control-Allow-Origin

一般團(tuán)隊都會有一個專門域名放置靜態(tài)資源,例如騰訊是gtimg.com,百度是bdimg.com;或者很多團(tuán)隊使用的是騰訊云或者阿里云的服務(wù)。

而主頁面所在域名往往不一樣,當(dāng)需要需要對canvas圖片進(jìn)行g(shù)etImageData()或toDataURL()操作的時候,跨域問題就出來了,而且跨域問題還不止一層。

首先,第一步,圖片服務(wù)器需要配置Access-Control-Allow-Origin信息,例如:

如PHP添加響應(yīng)頭信息,*通配符表示允許任意域名:

header("Access-Control-Allow-Origin: *");

或者指定域名:

header("Access-Control-Allow-Origin: www.zhangxinxu.com");

此時,Chrome瀏覽器就不會有Access-Control-Allow-Origin相關(guān)的錯誤信息了,但是,還會有其他的跨域錯誤信息。

二、canvas圖片getImageData cross-origin跨域問題

對于跨域的圖片,只要能夠在網(wǎng)頁中正常顯示出來,就可以使用canvas的drawImage() API繪制出來。但是如果你想更進(jìn)一步,通過getImageData()方法獲取圖片的完整的像素信息,則多半會出錯。

舉例來說,使用下面代碼獲取github上的自己頭像圖片信息:

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var img = new Image();
img.onload = function () {
    context.drawImage(this, 0, 0);
    context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

結(jié)果在Chrome瀏覽器下顯示如下錯誤:

Uncaught DOMException: Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data.

Firefox瀏覽器錯誤為:

SecurityError: The operation is insecure.

如果使用的是canvas.toDataURL()方法,則會報:

Failed to execute ‘toDataURL’ on ’HTMLCanvasElement’: Tainted canvased may not be exported

原因其實都是一樣的,跨域?qū)е隆?/p>

那有沒有什么辦法可以解決這個問題呢?

可以試試crossOrigin屬性。

三、HTML crossOrigin屬性解決資源跨域問題

在HTML5中,有些元素提供了支持CORS(Cross-Origin Resource Sharing)(跨域資源共享)的屬性,這些元素包括<img>,<video>,<script>等,而提供的屬性名就是crossOrigin屬性。

因此,上面的跨域問題可以這么處理:

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var img = new Image();
img.crossOrigin = '';
img.onload = function () {
    context.drawImage(this, 0, 0);
    context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

增加一個img.crossOrigin = ''即可,雖然JS代碼這里設(shè)置的是空字符串,實際上起作用的屬性值是anonymous。

crossOrigin可以有下面兩個值:

關(guān)鍵字 釋義
anonymous 元素的跨域資源請求不需要憑證標(biāo)志設(shè)置。
use-credentials 元素的跨域資源請求需要憑證標(biāo)志設(shè)置,意味著該請求需要提供憑證。

其中,只要crossOrigin的屬性值不是use-credentials,全部都會解析為anonymous,包括空字符串,包括類似'abc'這樣的字符。

例如:

img.crossOrigin = 'abc';
console.log(img.crossOrigin);    // 結(jié)果是'anonymous'

另外還有一點需要注意,那就是雖然沒有crossOrigin屬性,和設(shè)置crossOrigin="use-credentials"在默認(rèn)情況下都會報跨域出錯,但是性質(zhì)上卻不一樣,兩者有較大區(qū)別。

crossOrigin兼容性

IE11+(IE Edge),Safari,Chrome,F(xiàn)irefox瀏覽器均支持,IE9和IE10會報SecurityError安全錯誤,如下截圖:

四、crossOrigin屬性為什么可以解決資源跨域問題?

crossOrigin=anonymous相對于告訴對方服務(wù)器,你不需要帶任何非匿名信息過來。例如cookie,因此,當(dāng)前瀏覽器肯定是安全的。

就好比你要去別人家里拿一件衣服,crossOrigin=anonymous相對于告訴對方,我只要衣服,其他都不要。如果不說,可能對方在衣服里放個竊聽器什么的,就不安全了,瀏覽器就會阻止。

五、IE10瀏覽器不支持crossOrigin怎么辦?

我們請求圖片的時候,不是直接通過new Image(),而是借助ajax和URL.createObjectURL()方法曲線救國。

代碼如下:

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    var url = URL.createObjectURL(this.response);
    var img = new Image();
    img.onload = function () {
        // 此時你就可以使用canvas對img為所欲為了
        // ... code ...
        // 圖片用完后記得釋放內(nèi)存
        URL.revokeObjectURL(url);
    };
    img.src = url;
};
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();

此方法不僅IE10瀏覽器OK,原本支持crossOrigin的諸位瀏覽器也是支持的。

也就多走一個ajax請求,還可以!

根據(jù),根據(jù)實踐發(fā)現(xiàn),在IE瀏覽器下,如果請求的圖片過大,幾千像素那種,圖片會加載失敗,我猜是超過了blob尺寸限制。

六、結(jié)束語

最近工作中學(xué)到的一點小經(jīng)驗,希望可以幫到遇到類似問題的小伙伴。也希望大家多多支持腳本之家。

標(biāo)簽:萍鄉(xiāng) 盤錦 中山 阿壩 金昌 赤峰 綏化 聊城

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解如何解決canvas圖片getImageData,toDataURL跨域問題》,本文關(guān)鍵詞  詳解,如何,解決,canvas,圖片,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳解如何解決canvas圖片getImageData,toDataURL跨域問題》相關(guān)的同類信息!
  • 本頁收集關(guān)于詳解如何解決canvas圖片getImageData,toDataURL跨域問題的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    宝清县| 九龙城区| 延长县| 鄂尔多斯市| 闵行区| 广南县| 沽源县| 玛多县| 明溪县| 甘南县| 慈溪市| 西畴县| 始兴县| 出国| 阳东县| 嘉鱼县| 浑源县| 镇巴县| 远安县| 石嘴山市| 尚志市| 定兴县| 赣州市| 登封市| 普兰县| 崇义县| 常山县| 冷水江市| 随州市| 华坪县| 巫溪县| 临猗县| 孙吴县| 工布江达县| 禄劝| 西宁市| 闽清县| 余庆县| 昆明市| 陆良县| 民乐县|