摘要:通過跨域通過引入的不受同源策略的限制,所以我們可以通過標(biāo)簽引入一個或者是一個其他后綴形式如,等的文件,此文件返回一個函數(shù)的調(diào)用。
1.跨域的定義
只要協(xié)議、域名、端口有任何一個不同,就會被當(dāng)做為不同的域,如果從A域名訪問B域名上的資源就叫做跨域。
下面我們來看下幾種跨域的方法:
2.document.domain瀏覽器的同源策略有一些限制,第一,不能通過ajax方法去請求不同源的資源;第二,瀏覽器中不同域的框架之間是不能進行JS交互的。假如有一個頁面A,地址是http://www.domain.cn/A.html,在這個頁面里有個iframe,它的地址是http://domain.cn/B.html,顯然A和B是不同域的,所以我們沒法通過JS來訪問iframe中的數(shù)據(jù)和方法。
這種情況就就可以用document.domain來解決。
解決方法就是把http://www.domain.cn/A.html和http://domain.cn/B.html的document.domain設(shè)成相同的域名,需要注意的是, 我們只能把document.domain設(shè)置成自身或更高一級的父域,且主域必須相同。
在A中我們把設(shè)置document.domain:
在B頁面中我們也設(shè)置document.domain
但是這種方法只適合不同子域的框架間的交互。
3.location.hash在一個有iframe的頁面中,父窗口可以對iframe的URL進行讀寫,iframe也可以讀寫父窗口的URL。URL有一部分#加上后面的字符可以用來進行錨點定位,這部分就是hash。利用修改URL的hash部分可以進行雙向通信,從而達到跨域的目的。每個window通過改變其他window的location來發(fā)送消息,其他窗口通過監(jiān)聽URL變化的事件來接收消息。這個方式的通信會造成一些不必要的瀏覽器歷史記錄,而且有些瀏覽器不支持onhashchange事件,需要輪詢來獲知URL的改變,最后,這樣做也存在缺點,諸如數(shù)據(jù)直接暴露在了url中,數(shù)據(jù)容量和類型都有限等。下面是一個例子:
假如父頁面是baidu.com/a.html,iframe嵌入的頁面為google.com/b.html(此處省略了域名等url屬性),要實現(xiàn)此兩個頁面間的通信可以通過以下方法。
a.html傳送數(shù)據(jù)到b.html,a.html下修改iframe的src為:
google.com/b.html#paco
b.html監(jiān)聽到url發(fā)生變化,觸發(fā)相應(yīng)操作
b.html傳送數(shù)據(jù)到a.html,由于兩個頁面不在同一個域下IE、Chrome不允許修改parent.location.hash的值,所以要借助于父窗口域名下的一個代理iframe
b.html下創(chuàng)建一個隱藏的iframe,此iframe的src是baidu.com域下的,并掛上要傳送的hash數(shù)據(jù),如src=”http://www.baidu.com/proxy.ht...”
proxy.html監(jiān)聽到url發(fā)生變化,修改a.html的url(因為a.html和proxy.html同域,所以proxy.html可修改a.html的url hash)
a.html監(jiān)聽到url發(fā)生變化,觸發(fā)相應(yīng)操作
b.html的代碼:
try { parent.location.hash = "data"; } catch (e) { // ie、chrome的安全機制無法修改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頁面的關(guān)鍵代碼如下 :
//因為parent.parent(即baidu.com/a.html)和baidu.com/proxy.html屬于同一個域,所以可以改變其location.hash的值 parent.parent.location.hash = self.location.hash.substring(1);4.通過H5的postMessage()
IE8、Chrome、Firefox、Safari、Opera等瀏覽器都支持這個方法,這個功能主要包括接收信息的方法和發(fā)送消息的postMessage方法。比如damonare.cn域的A頁面通過iframe嵌入了一個google.com域的B頁面,可以通過以下方法實現(xiàn)A和B的通信:
A頁面通過postMessage發(fā)送消息:
window.onload = function() { var ifr = document.getElementById("ifr"); var targetOrigin = "http://www.google.com"; ifr.contentWindow.postMessage("hello world!", targetOrigin); }
B頁面通過message事件監(jiān)聽并接受消息:
var onmessage = function (event) { var data = event.data;//消息 var origin = event.origin;//消息來源地址 var source = event.source;//源Window對象 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); }
上面幾種方式都是頁面和iframe之間或者頁面和頁面之間的,下面介紹的是單向跨域,一般用于獲取數(shù)據(jù)。
5.通過JSOP跨域通過script引入的JS不受同源策略的限制,所以我們可以通過script標(biāo)簽引入一個js或者是一個其他后綴形式(如php,jsp等)的文件,此文件返回一個js函數(shù)的調(diào)用。
比如,有個a.html頁面,它里面的代碼需要利用ajax獲取一個不同域上的json數(shù)據(jù),假設(shè)這個json數(shù)據(jù)地址是http://damonare.cn/data.php,那么a.html中的代碼就可以這樣:
因為是當(dāng)做一個js文件來引入的,所以http://damonare.cn/data.php返回的必須是一個能執(zhí)行的js文件,所以這個頁面的php代碼可能是這樣的,這需要和后端約定好:
最終,輸出結(jié)果為:dosomething([‘a(chǎn)’,’b’,’c’]);
使用jQuery封裝的JSONP方法可以很方便的進行jsonp請求:
jquery會自動生成一個全局函數(shù)來替換callback=?中的問號,之后獲取到數(shù)據(jù)后又會自動銷毀,實際上就是起一個臨時代理函數(shù)的作用。$.getJSON方法會自動判斷是否跨域,不跨域的話,就調(diào)用普通的ajax方法;跨域的話,則會以異步加載js文件的形式來調(diào)用jsonp的回調(diào)函數(shù)。
優(yōu)點:不受到同源策略的影響,兼容性好,在一些古老的瀏覽器里也可以運行,不需要XMLHttpRequest或ActiveX的支持;并且在請求完畢后可以通過調(diào)用callback的方式回傳結(jié)果。
缺點:只支持GET請求,不能解決不同域的兩個頁面之間如何進行JavaScript調(diào)用的問題。
6. 通過CORS跨域CORS(Cross-Origin Resource Sharing)跨域資源共享,定義了必須在訪問跨域資源時,瀏覽器與服務(wù)器應(yīng)該如何溝通。CORS背后的基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務(wù)器進行溝通,從而決定請求或響應(yīng)是應(yīng)該成功還是失敗。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10。
因此,實現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實現(xiàn)了CORS接口,就可以跨源通信。
服務(wù)器端對于CORS的支持,主要就是通過設(shè)置Access-Control-Allow-Origin來進行的。如果瀏覽器檢測到相應(yīng)的設(shè)置,就可以允許Ajax進行跨域的訪問。
CORS與JSONP的對比:
JSONP只能實現(xiàn)GET請求,而CORS支持所有類型的HTTP請求;
使用CORS,開發(fā)者可以使用普通的XMLHttpRequest發(fā)起請求和獲得數(shù)據(jù),比起JSONP有
更好的錯誤處理。
CORS與JSONP相比,無疑更為先進、方便和可靠。
7.window.namewindow對象有個name屬性,該屬性有個特征:即在一個窗口(window)的生命周期內(nèi),窗口載入的所有的頁面都是共享一個window.name的,每個頁面對window.name都有讀寫的權(quán)限,window.name是持久存在一個窗口載入過的所有頁面中的,并不會因新頁面的載入而進行重置。
比如:我們在任意一個頁面輸入
window.name = "My window"s name"; setTimeout(function(){ window.location.; },1000)
進入damonare.cn頁面后我們再檢測再檢測 window.name :
window.name; // My window"s name
由于安全原因,瀏覽器始終會保持 window.name 是string 類型。
這種方法與 document.domain 方法相比,放寬了域名后綴要相同的限制,可以從任意頁面獲取 string 類型的數(shù)據(jù)。
8.反向代理服務(wù)器基礎(chǔ)思想很簡單,將你的服務(wù)器配置成需要 跨域獲取的資源 的反向代理服務(wù)器。
我們只需要配置nginx,在一個服務(wù)器上配置多個前綴來轉(zhuǎn)發(fā)http/https請求到多個真實的服務(wù)器即可。這樣,這個服務(wù)器上所有url都是相同的域名、協(xié)議和端口。因此,對于瀏覽器來說,這些url都是同源的,沒有跨域限制。而實際上,這些url實際上由物理服務(wù)器提供服務(wù)。這些服務(wù)器內(nèi)的javascript可以跨域調(diào)用所有這些服務(wù)器上的url。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/51148.html
摘要:前言騰訊一面,相比阿里一面來說,騰訊一面先給打電話預(yù)定時間,這也給了我們這些面試者去準(zhǔn)備的時間。其實閉包也就是指有權(quán)訪問另一個函數(shù)作用域的函數(shù)而已。常用的創(chuàng)建閉包的方法就是在函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)。 前言 騰訊一面,相比阿里一面來說,騰訊一面先給打電話預(yù)定時間,這也給了我們這些面試者去準(zhǔn)備的時間。但是也正是因為這種確定性,也有在等待電話的時候的心情的忐忑。 背景 我是一名大三學(xué)生,大一...
摘要:所謂同源是指協(xié)議域名端口三者相同,即便兩個不同的域名指向同一個地址,也非同源。那么怎樣解決跨域問題的呢通過跨域跨域跨域跨域跨域資源共享代理跨域中間件代理跨域音樂教程老師有用到協(xié)議跨域后端在頭部信息里面設(shè)置安全域名公司后端給解決過持續(xù)更新中 JavaScript篇 如何獲取瀏覽器URL中查詢字符串中的參數(shù)? 1.封裝方法 getUrlArgs(url) { const args =...
摘要:所謂同源是指協(xié)議域名端口三者相同,即便兩個不同的域名指向同一個地址,也非同源。那么怎樣解決跨域問題的呢通過跨域跨域跨域跨域跨域資源共享代理跨域中間件代理跨域音樂教程老師有用到協(xié)議跨域后端在頭部信息里面設(shè)置安全域名公司后端給解決過持續(xù)更新中 JavaScript篇 如何獲取瀏覽器URL中查詢字符串中的參數(shù)? 1.封裝方法 getUrlArgs(url) { const args =...
摘要:是的,方法被調(diào)用時,會在所有頁面腳本執(zhí)行完畢之后向目標(biāo)窗口派發(fā)一個消息。該消息有四個屬性需要注意屬性表示該的類型屬性為的第一個參數(shù)屬性表示調(diào)用方法時調(diào)用頁面的當(dāng)前狀態(tài)屬性記錄調(diào)用方法的窗口信息。 1.為什么要跨域 同源策略限制一個源加載的文檔或文檔與來自另一個源的資源進行交互。這是一個用于隔離潛在惡意文件的安全機制。什么是同源呢? 如果協(xié)議,端口(如果指定了一個)和域名對于兩個頁面是相...
摘要:跨域正確的打開方式經(jīng)過對同源策略的了解,我們應(yīng)該要消除對瀏覽器的誤解,同源策略是瀏覽器做的一件好事,是用來防御來自邪門歪道的攻擊,但總不能為了不讓壞人進門而把全部人都拒之門外吧。 跨域這兩個字就像一塊狗皮膏藥一樣黏在每一個前端開發(fā)者身上,無論你在工作上或者面試中無可避免會遇到這個問題。為了應(yīng)付面試,我每次都隨便背幾個方案,也不知道為什么要這樣干,反正面完就可以扔了,我想工作上也不會用到...
閱讀 3977·2021-09-22 16:03
閱讀 5311·2021-09-22 15:40
閱讀 1191·2021-09-06 15:02
閱讀 866·2019-08-30 15:53
閱讀 2215·2019-08-29 15:35
閱讀 1105·2019-08-23 18:22
閱讀 3333·2019-08-23 16:06
閱讀 643·2019-08-23 12:27