前端跨域解決方案總結

參考:https://segmentfault.com/a/1190000011145364

  • 簡單的跨域請求jsonp即可,復雜的cors谦絮,窗口之間JS跨域postMessage推正,開發(fā)環(huán)境下接口跨域用nginx反向代理或node中間件比較方便

同源策略

  • 同源是指"協(xié)議+域名+端口"三者相同跨新,即便兩個不同的域名指向同一個ip地址芹枷,也非同源
  • 如果缺少了同源策略嘉裤,瀏覽器很容易受到XSS莉测、CSFR等攻擊
  • 同源策略限制:
    • Cookie撇簿、LocalStorage 和 IndexDB 無法讀取
    • DOM 和 Js對象無法獲得
    • AJAX 請求不能發(fā)送
  • 跨域限制訪問恢口,其實是瀏覽器的限制孝宗,其實請求有發(fā)出去,對方服務器也有響應耕肩,只不過是被瀏覽器的同源策略攔下來

跨域解決方法

1. jsonp跨域

  • 利用script可以跨域的特性因妇,缺點是只能實現(xiàn)get請求
  • 應用場景:為了減輕web服務器的負載,我們把js猿诸,css沙峻,圖片等靜態(tài)資源分離到另一臺獨立域名的服務器上,在html頁面中跨域請求資源两芳。
<script>
    var script=document.createElement("script");
    script.type="text/javascript";
    //傳參并指定回調(diào)函數(shù)為onblack
     script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
     document.head.append(script);
     //回調(diào)函數(shù)
     function onBack(res) {
        alert(JSON.stringify(res));
    }
</script>
onBack({"status": true, "user": "admin"})
$.ajax({
    url: 'http://www.domain2.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 請求方式為jsonp
    jsonpCallback: "onBack",    // 自定義回調(diào)函數(shù)名
    data: {}
});
  • jsonpCallback:這個參數(shù)用來指定上面那個參數(shù)對應的回調(diào)函數(shù)名,如果不指定去枷,jQuery會自動生成一個隨機的函數(shù)名

2. 跨域資源共享(CORS)

  • cros支持所有形式的http請求
  • 普通跨域:只需要服務器端設置Access-Control-Allow-Origin即可怖辆,前端無需設置
  • 帶cookie請求的跨域(簡單請求):前端設置withCredentials屬性為true,服務器端響應必須攜帶Access-Control-Allow-Credentials:true的首部删顶,而且服務器的Access-Control-Allow-Origin不能設置為*竖螃,而必須設置允許跨域訪問的域名;
    • 同時逗余,Cookie依然遵循同源政策特咆,只有用服務器域名設置的Cookie才會上傳,其他域名的Cookie并不會上傳录粱,且(跨源)原網(wǎng)頁代碼中的document.cookie也無法讀取服務器域名下的Cookie腻格。
  • 非簡單請求
    • 非簡單請求是那種對服務器有特殊要求的請求,比如請求方法是PUT或DELETE啥繁,或者Content-Type字段的類型是application/json菜职。
    • 非簡單請求的CORS請求,會在正式通信之前旗闽,增加一次HTTP查詢請求酬核,稱為"預檢"請求(preflight)蜜另。
    • 瀏覽器先詢問服務器,當前網(wǎng)頁所在的域名是否在服務器的許可名單之中嫡意,以及可以使用哪些HTTP動詞和頭信息字段举瑰。只有得到肯定答復,瀏覽器才會發(fā)出正式的XMLHttpRequest請求蔬螟,否則就報錯
  • 簡單請求此迅,滿足:
      1. 請求方法是以下三種方法之一:
      • HEAD
      • GET
      • POST
    • (2)HTTP的頭信息不超出以下幾種字段:

      • Accept
      • Accept-Language
      • Content-Language
      • Last-Event-ID
      • Content-Type:只限于三個值application/x-www-form-urlencoded、multipart/form-data促煮、text/plain

3. nginx反向代理

  • 原理: 同源策略是瀏覽器的安全策略邮屁,不是HTTP協(xié)議的一部分。服務器端調(diào)用HTTP接口只是使用HTTP協(xié)議菠齿,不會執(zhí)行JS腳本佑吝,不需要同源策略,也就不存在跨越問題
  • 通過nginx配置一個代理服務器(域名與domain1相同绳匀,端口不同)做跳板機芋忿,反向代理訪問domain2接口,并且可以順便修改cookie中domain信息疾棵,方便當前域cookie寫入戈钢,實現(xiàn)跨域登錄
  • 配置:
    • 找到nginx的配置文件"nginx.conf"

4. WebSocket協(xié)議跨域

  • WebSocket protocol是HTML5一種新的協(xié)議。它實現(xiàn)了瀏覽器與服務器全雙工通信是尔,同時允許跨域通訊殉了,是server push技術的一種很好的實現(xiàn)。

5. document.domain + iframe跨域

  • 只限于主域相同拟枚,子域不同的跨域應用場景
  • 兩個頁面都通過js強制設置document.domain為基礎主域薪铜,就實現(xiàn)了同域
  1. 父窗口:(http://www.domain.com/a.html)
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
    document.domain = 'domain.com';
    var user = 'admin';
</script>
  1. 子窗口:(http://child.domain.com/b.html),通過window.parent獲取變量
<script>
    document.domain = 'domain.com';
    // 獲取父窗口中變量
    alert('get js data from parent ---> ' + window.parent.user);
</script>

6. postMessage跨域

postMessage是HTML5 XMLHttpRequest Level 2中的API恩溅,且是為數(shù)不多可以跨域操作的window屬性之一隔箍,它可用于解決以下方面的問題:

  1. 頁面和其打開的新窗口的數(shù)據(jù)傳遞
  2. 多窗口之間消息傳遞
  3. 頁面與嵌套的iframe消息傳遞
  4. 上面三個場景的跨域數(shù)據(jù)傳遞
  • 用法:postMessage(data,origin)方法接受兩個參數(shù)
    • data: html5規(guī)范支持任意基本類型或可復制的對象,但部分瀏覽器只支持字符串脚乡,所以傳參時最好用JSON.stringify()序列化蜒滩。
    • origin: 協(xié)議+主機+端口號,也可以設置為"*"奶稠,表示可以傳遞給任意窗口俯艰,如果要指定和當前窗口同源的話設置為"/"。
a.html:(http://www.domain1.com/a.html)
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>       
    var iframe = document.getElementById('iframe');
    iframe.onload = function() {
        var data = {
            name: 'aym'
        };
        // 向domain2傳送跨域數(shù)據(jù)
        iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
    };

    // 接受domain2返回數(shù)據(jù)
    window.addEventListener('message', function(e) {
        alert('data from domain2 ---> ' + e.data);
    }, false);
</script>
b.html:(http://www.domain2.com/b.html)
<script>
    // 接收domain1的數(shù)據(jù)
    window.addEventListener('message', function(e) {
        alert('data from domain1 ---> ' + e.data);

        var data = JSON.parse(e.data);
        if (data) {
            data.number = 16;

            // 處理后再發(fā)回domain1
            window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
        }
    }, false);
</script>

7. window.name

  • window對象有一個name屬性窒典,該屬性有一個特征:即在一個窗口的生命周期內(nèi)蟆炊,窗口載入的所有的頁面都是共享一個window.name的,每一個頁面對window.name都有讀寫的權限瀑志,window.name是持久的存在于一個窗口載入的所有頁面中的涩搓,并不會因為新的頁面的載入而被重置污秆。
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昧甘,隨后出現(xiàn)的幾起案子良拼,更是在濱河造成了極大的恐慌,老刑警劉巖充边,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庸推,死亡現(xiàn)場離奇詭異,居然都是意外死亡浇冰,警方通過查閱死者的電腦和手機贬媒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肘习,“玉大人际乘,你說我怎么就攤上這事∑澹” “怎么了脖含?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長投蝉。 經(jīng)常有香客問我养葵,道長,這世上最難降的妖魔是什么瘩缆? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任关拒,我火速辦了婚禮,結果婚禮上庸娱,老公的妹妹穿的比我還像新娘夏醉。我一直安慰自己,他們只是感情好涌韩,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著氯夷,像睡著了一般臣樱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腮考,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天雇毫,我揣著相機與錄音,去河邊找鬼踩蔚。 笑死棚放,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的馅闽。 我是一名探鬼主播飘蚯,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼馍迄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了局骤?” 一聲冷哼從身側響起攀圈,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎峦甩,沒想到半個月后赘来,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡凯傲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年犬辰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冰单。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡幌缝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出球凰,到底是詐尸還是另有隱情狮腿,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布呕诉,位于F島的核電站缘厢,受9級特大地震影響,放射性物質發(fā)生泄漏甩挫。R本人自食惡果不足惜贴硫,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伊者。 院中可真熱鬧英遭,春花似錦、人聲如沸亦渗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽法精。三九已至多律,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間搂蜓,已是汗流浹背狼荞。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留帮碰,地道東北人相味。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像殉挽,于是被迫代替她去往敵國和親丰涉。 傳聞我的和親對象是個殘疾皇子拓巧,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359