<h2>什么是跨域?</h2>
協(xié)議、域名、端口有一處不一樣,都是不同的域,兩個(gè)不同域的信息交互就是跨域。
<h2>跨域的具體實(shí)現(xiàn)</h2>
<h4>單向跨域(一般用于獲取數(shù)據(jù))</h4>
<strong>1.JSONP</strong>
原理:
JSONP (JSON with Padding)是一個(gè)簡(jiǎn)單高效的跨域方式,html中的script標(biāo)簽可以加載并執(zhí)行其他域的JavaScript,于是我們可以通過(guò)script標(biāo)記來(lái)動(dòng)態(tài)加載其他域的資源。
例如我要從域A的頁(yè)面pageA加載域B的數(shù)據(jù),那么在域B的頁(yè)面pageB中我以JavaScript的形式聲明pageA需要的數(shù)據(jù),然后在pageA中用script標(biāo)簽把pageB加載進(jìn)來(lái),那么pageB中的腳本就會(huì)得以執(zhí)行。JSONP在此基礎(chǔ)上加入了回調(diào)函數(shù),pageB加載完之后會(huì)執(zhí)行pageA中定義的函數(shù),所需要的數(shù)據(jù)會(huì)以參數(shù)的形式傳遞給該函數(shù)。JSONP易于實(shí)現(xiàn),但是也會(huì)存在一些安全隱患,如果第三方的腳本隨意地執(zhí)行,那么它就可以篡改頁(yè)面內(nèi)容,截獲敏感數(shù)據(jù)。但是在受信任的雙方傳遞數(shù)據(jù),JSONP是非常合適的選擇。
JSONP的優(yōu)點(diǎn)是:它不像XMLHttpRequest對(duì)象實(shí)現(xiàn)的Ajax請(qǐng)求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中都可以運(yùn)行,不需要XMLHttpRequest或ActiveX的支持;并且在請(qǐng)求完畢后可以通過(guò)調(diào)用callback的方式回傳結(jié)果。
JSONP的缺點(diǎn)則是:它只支持GET請(qǐng)求而不支持POST等其它類型的HTTP請(qǐng)求;它只支持跨域HTTP請(qǐng)求這種情況,不能解決不同域的兩個(gè)頁(yè)面之間如何進(jìn)行JavaScript調(diào)用的問(wèn)題。
<strong>2.flash URLLoader</strong>
flash有自己的一套安全策略,服務(wù)器可以通過(guò)crossdomain.xml文件來(lái)聲明能被哪些域的SWF文件訪問(wèn),SWF也可以通過(guò)API來(lái)確定自身能被哪些域的SWF加載。當(dāng)跨域訪問(wèn)資源時(shí),例如從域www.a.com請(qǐng)求域www.b.com上的數(shù)據(jù),我們可以借助flash來(lái)發(fā)送HTTP請(qǐng)求。首先,修改域www.b.com上的crossdomain.xml(一般存放在根目錄,如果沒(méi)有需要手動(dòng)創(chuàng)建) ,把www.a.com加入到白名單。其次,通過(guò)Flash URLLoader發(fā)送HTTP請(qǐng)求,最后,通過(guò)Flash API把響應(yīng)結(jié)果傳遞給JavaScript。Flash URLLoader是一種很普遍的跨域解決方案。
<strong>3.window.name</strong>
window對(duì)象的name屬性是一個(gè)很特別的屬性,當(dāng)該window的location變化,然后重新加載,它的name屬性可以依然保持不變。那么我們可以在頁(yè)面A中用iframe加載其他域的頁(yè)面B,而頁(yè)面B中用JavaScript把需要傳遞的數(shù)據(jù)賦值給window.name,iframe加載完成之后,頁(yè)面A修改iframe的地址,將其變成同域的一個(gè)地址,然后就可以讀出window.name的值了。這個(gè)方式非常適合單向的數(shù)據(jù)請(qǐng)求,而且協(xié)議簡(jiǎn)單、安全。不會(huì)像JSONP那樣不做限制地執(zhí)行外部腳本。
<h4>雙向跨域</h4>
<strong>1.document.domain</strong>
通過(guò)修改document的domain屬性,我們可以在域和子域或者不同的子域之間通信。同域策略認(rèn)為域和子域隸屬于不同的域,比如www.a.com和sub.a.com是不同的域,這時(shí),我們無(wú)法在www.a.com下的頁(yè)面中調(diào)用sub.a.com中定義的JavaScript方法。但是當(dāng)我們把它們document的domain屬性都修改為a.com,瀏覽器就會(huì)認(rèn)為它們處于同一個(gè)域下,那么我們就可以互相調(diào)用對(duì)方的method來(lái)通信了。
參考文章: