關(guān)于前端跨域處理的方法總結(jié)

前端跨域的那些總結(jié)

做項(xiàng)目期間一直有遇到關(guān)于跨域方面的問題,之前由于沒有上過生產(chǎn)環(huán)境,對(duì)于這方面的問題還不夠全面致讥,只是在前后端分離的方面遇到過,還是本地環(huán)境器赞,主要是基于JSONP解決的垢袱;在最近的Vue項(xiàng)目中遇到的本地開發(fā)環(huán)境的跨域解決臨時(shí)使用了dev中的index.js配置文件下內(nèi)置的proxyTable屬性配置解決跨域,測(cè)試環(huán)境行的通港柜,但是生產(chǎn)環(huán)境則不行请契,會(huì)踩到這,還是對(duì)跨域不夠清楚夏醉,最后重新復(fù)習(xí)了關(guān)于跨域方面的知識(shí)爽锥,對(duì)于線上環(huán)境配置了nginx反向代理后解決了跨域問題;下面畔柔,總結(jié)下對(duì)于跨域的認(rèn)識(shí)氯夷。

  • 為什么會(huì)有跨域問題的出現(xiàn)?

在我們的瀏覽器中有一條策略叫做“同源策略”靶擦,什么叫同源策略呢腮考?也就是當(dāng)我們前后端數(shù)據(jù)交互的時(shí)候,如果兩個(gè)頁面所處的端口或者子域名以及通信協(xié)議中的任何一個(gè)不同玄捕,那么當(dāng)你需要在違反同源策略的情況下在兩個(gè)頁面間通信時(shí)秸仙,就會(huì)出現(xiàn)跨域錯(cuò)誤,因?yàn)闉g覽器出于安全考慮桩盲,限制了此類訪問操作寂纪;但是日常開發(fā)操作中對(duì)于跨域操作的使用非常頻繁,所以如何解決此類限制赌结,完成不同頁面間的數(shù)據(jù)通信捞蛋,就是我們學(xué)習(xí)跨域操作及其工作原理的原因。

  • 前端有哪些處理方式可以解決跨域問題柬姚?
    1拟杉、document.domain

    1.場(chǎng)景:瀏覽器的同源策略有一些限制,首先量承,不能用ajax方法去請(qǐng)求不同源的資源搬设;并且穴店,瀏覽器中不同域的框架之間是不能進(jìn)行數(shù)據(jù)通信的,假如從‘https://www.baidu.com/request.html’中請(qǐng)求‘https://baidu.com/response.html’中的數(shù)據(jù)拿穴,在兩個(gè)不同的源中有一個(gè)iframe泣洞,但是由于是不同域,我們就沒法通過JS來訪問iframe中的數(shù)據(jù)和方法默色。
    解決辦法:我們可以將兩個(gè)不同源文件中的document.domain設(shè)成相同的域名球凰,但這里,需要提醒的一點(diǎn)是腿宰,我們?cè)谠O(shè)置document.domain時(shí)候呕诉,只能將其設(shè)置成自身或更高一級(jí)的父域,并且二者的主域必須相同吃度。

 ``` javascript
    <iframe src="https://www.baidu.com/request.html">
    <script>
         document.domain = " baidu.com " //這里是將A中的document.domain設(shè)置成主域
     </script>
  
<iframe src="https://baidu.com/response.html">
<script>
    document.domain = "baidu.com" //B頁面的document.domain設(shè)置相同的domain即可
</script>

 // 但是甩挫,此類解決辦法只適用于不同子域的框架間的交互。
  ```

2椿每、location.hash

場(chǎng)景:對(duì)于頁面中有iframe的頁面中捶闸,父窗口可以對(duì)iframe的url進(jìn)行讀寫。而在URL上有一部分#加上后面的字符可以用來進(jìn)行錨點(diǎn)定位拖刃,這部分就是這里會(huì)提到的hash。利用修改URL的hash部分可以進(jìn)行雙向通信贪绘,從而達(dá)到跨域的目的兑牡,每個(gè)window通過改變其他window的location來發(fā)送消息,其他窗口通過監(jiān)聽URL的變化來接受消息税灌,這個(gè)方式的通信會(huì)造成一些不必要的瀏覽器歷史記錄均函,而且有些瀏覽器不支持onhashchange事件,需要通過輪詢操作來獲取URL的改變菱涤,最后苞也,這樣做也存在一定問題,就是不僅數(shù)據(jù)會(huì)直接暴露在url中粘秆,數(shù)據(jù)容量和類型都有限如迟。

示例:假如當(dāng)前父頁面' baidu.com/request.html ',其中嵌入的頁面是’ xupt.edu.cn/response.html ‘攻走,要實(shí)現(xiàn)此兩個(gè)頁面間的通信可以通過以下方法殷勘。

> 1.request.html傳送數(shù)據(jù)到 response.html , request.html下修改為iframe的src為 'xupt.edu.cn/response.html'

>2.response.html監(jiān)聽到相應(yīng)數(shù)據(jù)發(fā)生變化昔搂,觸發(fā)對(duì)應(yīng)操作玲销。

>3.response.html傳送數(shù)據(jù)到 request.html 中,但是由于兩個(gè)頁面不在同源下摘符,會(huì)受到限制贤斜,所以要借助父窗口域名下的一個(gè)代理iframe策吠。

>4.request.html下創(chuàng)建一個(gè)隱藏的iframe, 此Iframe的src是baidu.com域下的瘩绒,并掛上要傳送的hash數(shù)據(jù)猴抹;如 src = "baidu.com/proxy.html"

>5.proxy.html監(jiān)聽到URL變化,修改a.html變化的URL,由于二者是同源草讶,所以在proxy.html中可修改a.html的url hash

>6.request.html監(jiān)聽到url變化洽糟,觸發(fā)相應(yīng)操作。
    // request.html 簡(jiǎn)單處理代碼
    try{
        parent.location.hash = 'data';
    }catch(e){
        // ie Chrome存在安全機(jī)制堕战,所以無法修改 parent.location.hash
        var _proxy = document.createElement('iframe');
        
        _proxy.style.display = 'none';
        _proxy.src = 'baidu.com/proxy.html';
    }
    
    // proxy.html關(guān)鍵代碼處理
    // 由于proxy.html和baidu.com/request.html存在與同域坤溃,所以可以正常改變其location.hash的值。
    
    parent.parent.location.hash = self.location.hash.substring(1);

3嘱丢、Html5的 postMessage( )
場(chǎng)景:該屬性各大主流瀏覽器均支持薪介,主要是包括接收信息的方法和發(fā)送信息的postMessage方法,比如A頁面通過內(nèi)嵌Iframe越驻,獲取一個(gè)B頁面汁政,就可以通過此方法實(shí)現(xiàn)A頁面和B頁面的通信。

    // A頁面通過 postMessage() 發(fā)送消息
    window.onload = function (){
        var _iframe = document.getElementById('ifr');  
        var targetOrigin = "https://www.google.com";  
        _iframe.contentWindow.postMessage('hello world!', targetOrigin);
    }
    
    // 在B頁面通過監(jiān)聽 message 事件并接收消息
    var onmessage = function (event){
      var data = event.data;//消息  
      var origin = event.origin;//消息來源地址  
      var source = event.source;//源Window對(duì)象  
      if(origin=="https://www.baidu.com"){  
        console.log(data);//hello world!  
      }  
    };
    
    if (typeof window.addEventListener != 'undefined') {  
      window.addEventListener('message', onmessage, false);  
    } else if (typeof window.attachEvent != 'undefined') {  
      //IE瀏覽器需要做特殊處理
      window.attachEvent('onmessage', onmessage);  
    }  

5缀旁、通過JSONP跨域
場(chǎng)景:通過script標(biāo)簽引入的JS不回受到瀏覽器同源策略的限制记劈,所以我們可以通過生成的script標(biāo)簽引入一個(gè)JS或者其他后綴形式的文件,但是這些文件返回的是一個(gè)JS函數(shù)的調(diào)用并巍。
> 如果作為一個(gè)JS文件引入目木,那么接口或請(qǐng)求地址返回的必須是一個(gè)可以執(zhí)行的JS文件,這里需要在編寫的時(shí)候和后端約定好規(guī)范懊渡。

  • 雖然此方法兼容性好刽射,不用XMLHttpRequest或ActiveX的支持;并且在請(qǐng)求完畢后可以通過調(diào)用callback的方式回傳結(jié)果剃执;但是只支持GET請(qǐng)求誓禁,不能解決不用域的兩個(gè)頁面之間如何進(jìn)行Javascript調(diào)用的問題。

6肾档、通過CROS跨域
場(chǎng)景:CROS全稱是跨域資源共享摹恰,定義了必須在訪問跨域資源時(shí)瀏覽器與服務(wù)器應(yīng)該如何溝通,CROS背后的基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務(wù)器進(jìn)行數(shù)據(jù)通信怒见,主流瀏覽器均支持該功能戒祠,但是IE瀏覽器版本不能低于IE10。并且速种,使用此方法的關(guān)鍵在于服務(wù)器的配置處理姜盈,只要服務(wù)器實(shí)現(xiàn)了CORS接口,就可以實(shí)現(xiàn)跨域通信配阵。

在服務(wù)端里面馏颂,對(duì)于CROS的支持示血,主要是通過設(shè)置響應(yīng)頭Access-Control-Allow-Origin來進(jìn)行,如果瀏覽器監(jiān)測(cè)到相應(yīng)的設(shè)置救拉,就可以允許跨域通信請(qǐng)求难审。
上邊提到的JSONP實(shí)現(xiàn)跨域,有很大的局限性亿絮,只支持GET請(qǐng)求告喊,但是在CROS實(shí)現(xiàn)的跨域請(qǐng)求訪問中,支持所有的數(shù)據(jù)請(qǐng)求方式派昧,并且有更好的錯(cuò)誤處理方式黔姜,能夠接收簡(jiǎn)單的XMLHttpRequest發(fā)起的請(qǐng)求。

7蒂萎、設(shè)置Window.name屬性
場(chǎng)景: 每個(gè)window對(duì)象有個(gè)name屬性秆吵,該屬性有個(gè)特征:在一個(gè)創(chuàng)口的生命周期之內(nèi),窗口載入的所有頁面都是共享一個(gè)window.name的五慈,每個(gè)頁面對(duì)window.name都有讀寫的權(quán)限纳寂,window.name是持久存在一個(gè)窗口載入過的所有頁面中的,并不會(huì)因?yàn)樾马撁娴妮d入而進(jìn)行重置泻拦;并且毙芜,由于安全原因限制,瀏覽器始終都會(huì)保持window,name是 string 類型争拐。

這種方法與document.domain相比腋粥,放寬了域名后綴要相同的限制,可以從任意頁面獲取string類型的數(shù)據(jù)陆错。

8、配置反向代理服務(wù)器
場(chǎng)景:基本解決思路就是將其服務(wù)所在的服務(wù)器配置成所需的跨域資源訪問的反向代理服務(wù)器金赦,在nginx服務(wù)器配置上音瓷,將當(dāng)前接收到需要發(fā)送的各類請(qǐng)求鏈接,按照實(shí)際需要夹抗,配置好轉(zhuǎn)發(fā)規(guī)則绳慎,通過服務(wù)器處理相應(yīng)的請(qǐng)求鏈接,對(duì)于瀏覽器來說漠烧,這些請(qǐng)求是發(fā)送到本機(jī)服務(wù)器的杏愤,是同源的,而實(shí)際請(qǐng)求是又服務(wù)器進(jìn)行轉(zhuǎn)發(fā)已脓,這樣就不會(huì)觸及瀏覽器的同源策略限制珊楼,就能實(shí)現(xiàn)正常的跨域通信請(qǐng)求等操作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末度液,一起剝皮案震驚了整個(gè)濱河市厕宗,隨后出現(xiàn)的幾起案子画舌,更是在濱河造成了極大的恐慌,老刑警劉巖已慢,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曲聂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡佑惠,警方通過查閱死者的電腦和手機(jī)朋腋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膜楷,“玉大人旭咽,你說我怎么就攤上這事“呀” “怎么了轻专?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)察蹲。 經(jīng)常有香客問我请垛,道長(zhǎng),這世上最難降的妖魔是什么洽议? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任宗收,我火速辦了婚禮,結(jié)果婚禮上亚兄,老公的妹妹穿的比我還像新娘混稽。我一直安慰自己,他們只是感情好审胚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布匈勋。 她就那樣靜靜地躺著,像睡著了一般膳叨。 火紅的嫁衣襯著肌膚如雪洽洁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天菲嘴,我揣著相機(jī)與錄音饿自,去河邊找鬼。 笑死龄坪,一個(gè)胖子當(dāng)著我的面吹牛昭雌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播健田,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烛卧,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了妓局?” 一聲冷哼從身側(cè)響起唱星,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤雳旅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后间聊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體攒盈,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年哎榴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了型豁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尚蝌,死狀恐怖迎变,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情飘言,我是刑警寧澤衣形,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站姿鸿,受9級(jí)特大地震影響谆吴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苛预,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一句狼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧热某,春花似錦腻菇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秘遏,卻和暖如春丘薛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背垄提。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工榔袋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留周拐,地道東北人铡俐。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像妥粟,于是被迫代替她去往敵國(guó)和親审丘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 跨域資源共享 CORS 對(duì)于web開發(fā)來講勾给,由于瀏覽器的同源策略滩报,我們需要經(jīng)常使用一些hack的方法去跨域獲取資源...
    默默先生Alec閱讀 591評(píng)論 0 0
  • 什么是跨域锅知? 2.) 資源嵌入:、脓钾、售睹、等dom標(biāo)簽,還有樣式中background:url()可训、@font-fac...
    電影里的夢(mèng)i閱讀 2,374評(píng)論 0 5
  • 我在水中彈琴 楓葉從身邊飄落 四周是一片靜謐 只有我的琴音 和著水聲泠泠 一片安寧 這片安寧啊 連月兒都被吸引 映...
    謝子章閱讀 185評(píng)論 1 1
  • 原來當(dāng)你開始干事情的時(shí)候昌妹,一切會(huì)變得繁雜而有意義。 連自己都把握不住自己的人如何讓別人去信任你握截。...
    神賜Doreen閱讀 164評(píng)論 0 0
  • 我想,對(duì)父輩的理解胯努,對(duì)選擇的堅(jiān)守牢裳,這是對(duì)昨天的尊重,也是對(duì)明天的負(fù)責(zé)康聂。 剛立春贰健,老天爺應(yīng)該是也眷戀這早春的時(shí)光,開...
    騾子看電影閱讀 273評(píng)論 0 0