成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端跨域總結(jié)

Yang_River / 3420人閱讀

摘要:通過(guò)跨域通過(guò)引入的不受同源策略的限制,所以我們可以通過(guò)標(biāo)簽引入一個(gè)或者是一個(gè)其他后綴形式如,等的文件,此文件返回一個(gè)函數(shù)的調(diào)用。

1.跨域的定義

只要協(xié)議、域名、端口有任何一個(gè)不同,就會(huì)被當(dāng)做為不同的域,如果從A域名訪問(wèn)B域名上的資源就叫做跨域。

下面我們來(lái)看下幾種跨域的方法:

2.document.domain

瀏覽器的同源策略有一些限制,第一,不能通過(guò)ajax方法去請(qǐng)求不同源的資源;第二,瀏覽器中不同域的框架之間是不能進(jìn)行JS交互的。假如有一個(gè)頁(yè)面A,地址是http://www.domain.cn/A.html,在這個(gè)頁(yè)面里有個(gè)iframe,它的地址是http://domain.cn/B.html,顯然A和B是不同域的,所以我們沒(méi)法通過(guò)JS來(lái)訪問(wèn)iframe中的數(shù)據(jù)和方法。

這種情況就就可以用document.domain來(lái)解決。

解決方法就是把http://www.domain.cn/A.html和http://domain.cn/B.html的document.domain設(shè)成相同的域名,需要注意的是, 我們只能把document.domain設(shè)置成自身或更高一級(jí)的父域,且主域必須相同。

在A中我們把設(shè)置document.domain:


 

在B頁(yè)面中我們也設(shè)置document.domain

但是這種方法只適合不同子域的框架間的交互。

3.location.hash

在一個(gè)有iframe的頁(yè)面中,父窗口可以對(duì)iframe的URL進(jìn)行讀寫(xiě),iframe也可以讀寫(xiě)父窗口的URL。URL有一部分#加上后面的字符可以用來(lái)進(jìn)行錨點(diǎn)定位,這部分就是hash。利用修改URL的hash部分可以進(jìn)行雙向通信,從而達(dá)到跨域的目的。每個(gè)window通過(guò)改變其他window的location來(lái)發(fā)送消息,其他窗口通過(guò)監(jiān)聽(tīng)URL變化的事件來(lái)接收消息。這個(gè)方式的通信會(huì)造成一些不必要的瀏覽器歷史記錄,而且有些瀏覽器不支持onhashchange事件,需要輪詢來(lái)獲知URL的改變,最后,這樣做也存在缺點(diǎn),諸如數(shù)據(jù)直接暴露在了url中,數(shù)據(jù)容量和類型都有限等。下面是一個(gè)例子:

假如父頁(yè)面是baidu.com/a.html,iframe嵌入的頁(yè)面為google.com/b.html(此處省略了域名等url屬性),要實(shí)現(xiàn)此兩個(gè)頁(yè)面間的通信可以通過(guò)以下方法。

a.html傳送數(shù)據(jù)到b.html,a.html下修改iframe的src為:
google.com/b.html#paco

b.html監(jiān)聽(tīng)到url發(fā)生變化,觸發(fā)相應(yīng)操作

b.html傳送數(shù)據(jù)到a.html,由于兩個(gè)頁(yè)面不在同一個(gè)域下IE、Chrome不允許修改parent.location.hash的值,所以要借助于父窗口域名下的一個(gè)代理iframe

b.html下創(chuàng)建一個(gè)隱藏的iframe,此iframe的src是baidu.com域下的,并掛上要傳送的hash數(shù)據(jù),如src=”http://www.baidu.com/proxy.ht...”

proxy.html監(jiān)聽(tīng)到url發(fā)生變化,修改a.html的url(因?yàn)閍.html和proxy.html同域,所以proxy.html可修改a.html的url hash)

a.html監(jiān)聽(tīng)到url發(fā)生變化,觸發(fā)相應(yīng)操作

b.html的代碼:

try {  
    parent.location.hash = "data";  
} catch (e) {  
    // ie、chrome的安全機(jī)制無(wú)法修改parent.location.hash,  
    var ifrproxy = document.createElement("iframe");  
    ifrproxy.style.display = "none";  
    ifrproxy.src = "http://www.baidu.com/proxy.html#data";  
    document.body.appendChild(ifrproxy);  
}

proxy.html頁(yè)面的關(guān)鍵代碼如下 :

//因?yàn)閜arent.parent(即baidu.com/a.html)和baidu.com/proxy.html屬于同一個(gè)域,所以可以改變其location.hash的值  
parent.parent.location.hash = self.location.hash.substring(1);
4.通過(guò)H5的postMessage()

IE8、Chrome、Firefox、Safari、Opera等瀏覽器都支持這個(gè)方法,這個(gè)功能主要包括接收信息的方法和發(fā)送消息的postMessage方法。比如damonare.cn域的A頁(yè)面通過(guò)iframe嵌入了一個(gè)google.com域的B頁(yè)面,可以通過(guò)以下方法實(shí)現(xiàn)A和B的通信:

A頁(yè)面通過(guò)postMessage發(fā)送消息:

window.onload = function() {  
    var ifr = document.getElementById("ifr");  
    var targetOrigin = "http://www.google.com";  
    ifr.contentWindow.postMessage("hello world!", targetOrigin);  
}

B頁(yè)面通過(guò)message事件監(jiān)聽(tīng)并接受消息:

var onmessage = function (event) {  
  var data = event.data;//消息  
  var origin = event.origin;//消息來(lái)源地址  
  var source = event.source;//源Window對(duì)象  
  if(origin=="http://www.baidu.com"){  
console.log(data);//hello world!  
  }  
};  
if (typeof window.addEventListener != "undefined") {  
  window.addEventListener("message", onmessage, false);  
} else if (typeof window.attachEvent != "undefined") {  
  //for ie  
  window.attachEvent("onmessage", onmessage);  
}  

上面幾種方式都是頁(yè)面和iframe之間或者頁(yè)面和頁(yè)面之間的,下面介紹的是單向跨域,一般用于獲取數(shù)據(jù)。

5.通過(guò)JSOP跨域

通過(guò)script引入的JS不受同源策略的限制,所以我們可以通過(guò)script標(biāo)簽引入一個(gè)js或者是一個(gè)其他后綴形式(如php,jsp等)的文件,此文件返回一個(gè)js函數(shù)的調(diào)用。
比如,有個(gè)a.html頁(yè)面,它里面的代碼需要利用ajax獲取一個(gè)不同域上的json數(shù)據(jù),假設(shè)這個(gè)json數(shù)據(jù)地址是http://damonare.cn/data.php,那么a.html中的代碼就可以這樣:


因?yàn)槭钱?dāng)做一個(gè)js文件來(lái)引入的,所以http://damonare.cn/data.php返回的必須是一個(gè)能執(zhí)行的js文件,所以這個(gè)頁(yè)面的php代碼可能是這樣的,這需要和后端約定好:

最終,輸出結(jié)果為:dosomething([‘a(chǎn)’,’b’,’c’]);
使用jQuery封裝的JSONP方法可以很方便的進(jìn)行jsonp請(qǐng)求:

jquery會(huì)自動(dòng)生成一個(gè)全局函數(shù)來(lái)替換callback=?中的問(wèn)號(hào),之后獲取到數(shù)據(jù)后又會(huì)自動(dòng)銷毀,實(shí)際上就是起一個(gè)臨時(shí)代理函數(shù)的作用。$.getJSON方法會(huì)自動(dòng)判斷是否跨域,不跨域的話,就調(diào)用普通的ajax方法;跨域的話,則會(huì)以異步加載js文件的形式來(lái)調(diào)用jsonp的回調(diào)函數(shù)。

優(yōu)點(diǎn):不受到同源策略的影響,兼容性好,在一些古老的瀏覽器里也可以運(yùn)行,不需要XMLHttpRequest或ActiveX的支持;并且在請(qǐng)求完畢后可以通過(guò)調(diào)用callback的方式回傳結(jié)果。

缺點(diǎn):只支持GET請(qǐng)求,不能解決不同域的兩個(gè)頁(yè)面之間如何進(jìn)行JavaScript調(diào)用的問(wèn)題。

6. 通過(guò)CORS跨域

CORS(Cross-Origin Resource Sharing)跨域資源共享,定義了必須在訪問(wèn)跨域資源時(shí),瀏覽器與服務(wù)器應(yīng)該如何溝通。CORS背后的基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務(wù)器進(jìn)行溝通,從而決定請(qǐng)求或響應(yīng)是應(yīng)該成功還是失敗。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10。

因此,實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了CORS接口,就可以跨源通信。

服務(wù)器端對(duì)于CORS的支持,主要就是通過(guò)設(shè)置Access-Control-Allow-Origin來(lái)進(jìn)行的。如果瀏覽器檢測(cè)到相應(yīng)的設(shè)置,就可以允許Ajax進(jìn)行跨域的訪問(wèn)。

CORS與JSONP的對(duì)比:

JSONP只能實(shí)現(xiàn)GET請(qǐng)求,而CORS支持所有類型的HTTP請(qǐng)求;

使用CORS,開(kāi)發(fā)者可以使用普通的XMLHttpRequest發(fā)起請(qǐng)求和獲得數(shù)據(jù),比起JSONP有
更好的錯(cuò)誤處理。

CORS與JSONP相比,無(wú)疑更為先進(jìn)、方便和可靠。

7.window.name

window對(duì)象有個(gè)name屬性,該屬性有個(gè)特征:即在一個(gè)窗口(window)的生命周期內(nèi),窗口載入的所有的頁(yè)面都是共享一個(gè)window.name的,每個(gè)頁(yè)面對(duì)window.name都有讀寫(xiě)的權(quán)限,window.name是持久存在一個(gè)窗口載入過(guò)的所有頁(yè)面中的,并不會(huì)因新頁(yè)面的載入而進(jìn)行重置。

比如:我們?cè)谌我庖粋€(gè)頁(yè)面輸入

window.name = "My window"s name";
setTimeout(function(){
    window.location.;
},1000)

進(jìn)入damonare.cn頁(yè)面后我們?cè)贆z測(cè)再檢測(cè) window.name :

window.name; // My window"s name

由于安全原因,瀏覽器始終會(huì)保持 window.name 是string 類型。

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

8.反向代理服務(wù)器

基礎(chǔ)思想很簡(jiǎn)單,將你的服務(wù)器配置成需要 跨域獲取的資源 的反向代理服務(wù)器。

我們只需要配置nginx,在一個(gè)服務(wù)器上配置多個(gè)前綴來(lái)轉(zhuǎn)發(fā)http/https請(qǐng)求到多個(gè)真實(shí)的服務(wù)器即可。這樣,這個(gè)服務(wù)器上所有url都是相同的域名、協(xié)議和端口。因此,對(duì)于瀏覽器來(lái)說(shuō),這些url都是同源的,沒(méi)有跨域限制。而實(shí)際上,這些url實(shí)際上由物理服務(wù)器提供服務(wù)。這些服務(wù)器內(nèi)的javascript可以跨域調(diào)用所有這些服務(wù)器上的url。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/51148.html

相關(guān)文章

  • 2018年騰訊前端一面總結(jié)(面向2019屆學(xué)生)

    摘要:前言騰訊一面,相比阿里一面來(lái)說(shuō),騰訊一面先給打電話預(yù)定時(shí)間,這也給了我們這些面試者去準(zhǔn)備的時(shí)間。其實(shí)閉包也就是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域的函數(shù)而已。常用的創(chuàng)建閉包的方法就是在函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。 前言 騰訊一面,相比阿里一面來(lái)說(shuō),騰訊一面先給打電話預(yù)定時(shí)間,這也給了我們這些面試者去準(zhǔn)備的時(shí)間。但是也正是因?yàn)檫@種確定性,也有在等待電話的時(shí)候的心情的忐忑。 背景 我是一名大三學(xué)生,大一...

    Kosmos 評(píng)論0 收藏0
  • 總結(jié)系列〕前端面試題精華篩選

    摘要:所謂同源是指協(xié)議域名端口三者相同,即便兩個(gè)不同的域名指向同一個(gè)地址,也非同源。那么怎樣解決跨域問(wèn)題的呢通過(guò)跨域跨域跨域跨域跨域資源共享代理跨域中間件代理跨域音樂(lè)教程老師有用到協(xié)議跨域后端在頭部信息里面設(shè)置安全域名公司后端給解決過(guò)持續(xù)更新中 JavaScript篇 如何獲取瀏覽器URL中查詢字符串中的參數(shù)? 1.封裝方法 getUrlArgs(url) { const args =...

    lyning 評(píng)論0 收藏0
  • 總結(jié)系列〕前端面試題精華篩選

    摘要:所謂同源是指協(xié)議域名端口三者相同,即便兩個(gè)不同的域名指向同一個(gè)地址,也非同源。那么怎樣解決跨域問(wèn)題的呢通過(guò)跨域跨域跨域跨域跨域資源共享代理跨域中間件代理跨域音樂(lè)教程老師有用到協(xié)議跨域后端在頭部信息里面設(shè)置安全域名公司后端給解決過(guò)持續(xù)更新中 JavaScript篇 如何獲取瀏覽器URL中查詢字符串中的參數(shù)? 1.封裝方法 getUrlArgs(url) { const args =...

    Thanatos 評(píng)論0 收藏0
  • 前端跨域方法總結(jié)

    摘要:是的,方法被調(diào)用時(shí),會(huì)在所有頁(yè)面腳本執(zhí)行完畢之后向目標(biāo)窗口派發(fā)一個(gè)消息。該消息有四個(gè)屬性需要注意屬性表示該的類型屬性為的第一個(gè)參數(shù)屬性表示調(diào)用方法時(shí)調(diào)用頁(yè)面的當(dāng)前狀態(tài)屬性記錄調(diào)用方法的窗口信息。 1.為什么要跨域 同源策略限制一個(gè)源加載的文檔或文檔與來(lái)自另一個(gè)源的資源進(jìn)行交互。這是一個(gè)用于隔離潛在惡意文件的安全機(jī)制。什么是同源呢? 如果協(xié)議,端口(如果指定了一個(gè))和域名對(duì)于兩個(gè)頁(yè)面是相...

    PAMPANG 評(píng)論0 收藏0
  • 前端跨域總結(jié)

    摘要:跨域正確的打開(kāi)方式經(jīng)過(guò)對(duì)同源策略的了解,我們應(yīng)該要消除對(duì)瀏覽器的誤解,同源策略是瀏覽器做的一件好事,是用來(lái)防御來(lái)自邪門(mén)歪道的攻擊,但總不能為了不讓壞人進(jìn)門(mén)而把全部人都拒之門(mén)外吧。 跨域這兩個(gè)字就像一塊狗皮膏藥一樣黏在每一個(gè)前端開(kāi)發(fā)者身上,無(wú)論你在工作上或者面試中無(wú)可避免會(huì)遇到這個(gè)問(wèn)題。為了應(yīng)付面試,我每次都隨便背幾個(gè)方案,也不知道為什么要這樣干,反正面完就可以扔了,我想工作上也不會(huì)用到...

    Wuv1Up 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<