后端代理解決資源跨域

canvas 跨域問題

如果canvas中所繪制的Image或者資源有跨域,則對canvas中的數據進行操作往往會報錯,例如在地圖導出或者操作像素時

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

canvas的CanvasRenderingContext2D屬于瀏覽器中的對象,如果曾經渲染過跨域資源。 瀏覽器就認定canvas已經被污染(tainted)了。問題很常見,所以可以對canvas所加載的資源,特別是圖片設置跨域,

image.crossOrigin="anonymous";

對image對象的crossOrigin屬性設置anonymous,那么在image.src= "http://some.com/demo.jpg" 的時候,發送的GET請求,到達對方服務器some.com,如果碰巧對方服務器對這類資源的不限制訪問,也就是response header的 Access-Control-Allow-Origin 字段為 "*" ,那么我們的瀏覽器可成功獲取資源。

Access-Control-Allow-Origin 這個response header 很常用,確保了服務器對資源的跨域限制。如果需要限定白名單,就直接把白名單的domain或者ip放到value 中。 關于Ol3的切片跨域問題,公瑾大神在這篇文章中已經說得很清楚了,不再贅述

請求有跨域限制的服務器資源

但如果對方服務器限制跨域訪問,那不論咱們的前端代碼如何設定,都無法繞開。最好的辦法之一就是后端代理,DEMO ,點左邊這個鏈接可以在線體驗下。。(切片走的代理,另外隨便輸入個公交線路數字,也是走后臺代理的)

在前端需要請求跨域資源時,給URL加上同域下的后臺代理前綴,讓這個請求走代理轉發一下。。真心是老技術。所以隨便寫寫,不花心思完善了。以Nodejs為例的寫了一個后臺代理模塊,主要內容如下:

var Proxy = function (req, res) { 
    // proxy the client request.
    (function() {
        console.log("receive client req : "+ req.query['proxyURI']);
        var target = req.query['proxyURI'];
        // thisPlace should first check localFile if exists, res localFile directly.. 這邊呢,接收到前端的請求,把實際要請求的地址拿到,后臺轉發。
        http.get(target, function(response) {  
            console.log("Proxy got response: " + response.statusCode);
            var resContentType = response.headers["content-type"];
            res.setHeader("Content-Type", resContentType);
            var buffer = [];
            response.on('data', (chunk) => {
                buffer.push(chunk);                
            });
            response.on('end', () => {
                // Buffer toString. 'ascii'/'base64'
                var buff = Buffer.concat(buffer);
                for(var k in strategies) {
                    if (resContentType.indexOf(k) > -1) {
                        // ready to save buffer to localFile.. 碰到策略中指定的文件類型,在本地緩存下
                        try {
                            var ext = resContentType.split("/")[1];
                            var tmpArr = target.split("/");
                            var fileName = tmpArr[tmpArr.length-2] + "_" + tmpArr[tmpArr.length-1] + "." + ext;
                            var finalName = "./Asset/tiles/" + fileName;
                            fs.exists(finalName, function(exists) {
                                if (exists) {
                                    // 如果這個文件本地緩存過了,直接發回前端。
                                    res.sendFile(finalName, {
                                        root: __dirname
                                    });
                                } else {
                                    fs.writeFileSync("./Asset/tiles/" + fileName, buff);
                                    res.sendFile(finalName, {
                                        root: __dirname
                                    });
                                }
                            });
                            
                            return;
                        } catch (error) {
                            console.error("proxyImage error.");
                            res.end("proxyImage error.");
                        }                        
                    }
                }
                // 非二進制文件類型(JSON,HTML等),直接發回字符串
                res.end(buff.toString());
            });
        }).on('error', function(e) {  
            console.error("Proxy got error: " + e.message);
        });
    })()
}

module.exports = Proxy;

我記得openlayer2的時候官方有贈送一個python版本的代理,現在ol3好像沒了。所以突然發現這個代理還有:

切片下載的功能!! \(o)/,后臺會隨著前端的請求過程,緩存圖片等文件。


一起搞項目

這個代理模塊拿來改改參數就可以勉強用了。所以需要的弟兄們直接去 Github項目地址 取用即可

DEMO截圖

這個項目是最近比較常用的,包括了平日里做的一些小插件和DEMO之類的。比如:

還有另外一個ThreeJS項目有空也在弄,其實想基于ES6做一些模塊化的ThreeJS開發,用于搭建三維游戲場景。之前代碼寫得比較隨意,現在必須模塊化,不然沒法看。。先來個DEMO瞅瞅,數據量大多等會兒,鼠標右鍵拖動場景。

希望有人一起搞啊,很有趣的項目。。。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容