跨域的幾種解決方案

跨域是web開(kāi)發(fā)中經(jīng)常會(huì)遇到的情況赊堪,只出現(xiàn)在瀏覽器端。本文列舉了一些常見(jiàn)的跨域情況竖哩,和解決方案哭廉。

什么是跨域,為什么會(huì)有跨域相叁?

首先什么是跨域遵绰,簡(jiǎn)單地理解就是因?yàn)镴avaScript同源策略的限制。
如 a.com 下的js 無(wú)法和b.com 的js通信增淹。這是瀏覽器為了安全而設(shè)定的策略

只有域名相同才不會(huì)有跨域的情況街立。

以下情況都會(huì)出現(xiàn)跨域:
a.com 和 b.com 不同域名
www.a.coma.com 不同二級(jí)域名
a.com 和 a.com:3000 不同端口
http://a.comhttps://a.com 不同協(xié)議
app.a.com 和 pc.a.com 不同二級(jí)域名

以上可見(jiàn) 只有域名嚴(yán)格一致才不會(huì)出現(xiàn)跨域

特別注意兩點(diǎn):
第一,如果是協(xié)議和端口造成的跨域問(wèn)題“前臺(tái)”是無(wú)能為力的埠通,只能通過(guò)后臺(tái)代理。這里不細(xì)說(shuō)逛犹。

第二:在跨域問(wèn)題上端辱,域僅僅是通過(guò)“URL的首部”來(lái)識(shí)別而不會(huì)去嘗試判斷相同的ip地址對(duì)應(yīng)著兩個(gè)域或兩個(gè)域是否在同一個(gè)ip上。"URL的首部" 指 https:// (協(xié)議)www.myweb.com(域名) :8080(端口)

常見(jiàn)的情況和解決方案

1.jsonp 跨域訪問(wèn)接口

// 在a.com下
$.ajax({
    url: 'b.com/getjson'?cb=?$a=1&b=2, // cb=? jquery的jsonp 會(huì)把此處的虽画?
    type: 'jsonp',                     //替換為jsonpCallback
    jsonpCallback:'jsonpCallback',  // 發(fā)出的請(qǐng)求為b.com/getjson'?cb=jsonpCallback$a=1&b=2
    success:function(data){
        console.log(data)
    }
})

jsonp的原理:
雖然js是受到同源策略舞蔽,但是引用js文件,img码撰,css文件是不會(huì)受到限制的渗柿。聰明的你此時(shí)是否已經(jīng)知道了答案。

沒(méi)錯(cuò)原理就是動(dòng)態(tài)創(chuàng)建script脖岛。jquery在發(fā)請(qǐng)求前生產(chǎn)了一個(gè)jsonpCallback函數(shù)朵栖。然后向b.com請(qǐng)求了一個(gè)js文件
服務(wù)器根據(jù)cb的值返回一個(gè)jsonpCallback(jsonDate);即這個(gè)js文件被瀏覽器解析后執(zhí)行了之前定義的函數(shù)。

這種方法非常常見(jiàn)柴梆,方便好用陨溅。
缺點(diǎn)是
1.需要后端配合提供jsonp接口。
2.因?yàn)槭莿?dòng)態(tài)創(chuàng)建script標(biāo)簽绍在,所以只能get门扇,不能post雹有。 安全性要大大低于post,不適合發(fā)送機(jī)密信息臼寄。

2.document.domain+iframe的設(shè)置

對(duì)于主域相同而子域不同的例子
如在a.com 頁(yè)面里有一個(gè) pc.a.com 的iframe
我們只要在2個(gè)頁(yè)面里都設(shè)置 document.domain = 'a.com';
代碼如下:

var ifr = document.createElement('iframe');
ifr.src = 'http://pc.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
    var doc = ifr.contentDocument || ifr.contentWindow.document;
    // 在這里操縱b.html
    alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};

這種方式適用于{www.kuqin.com, kuqin.com, script.kuqin.com, css.kuqin.com}中的任何頁(yè)面相互通信

注意:
0霸奕、document.domain 不能改變主域。a.com 不能設(shè)為b.com 吉拳。
1质帅、安全性,當(dāng)一個(gè)站點(diǎn)(b.a.com)被攻擊后合武,另一個(gè)站點(diǎn)(c.a.com)會(huì)引起安全漏洞临梗。
2、如果一個(gè)頁(yè)面中引入多個(gè)iframe稼跳,要想能夠操作所有iframe盟庞,必須都得設(shè)置相同domain。

3汤善、利用iframe和location.hash

1什猖、a.com a頁(yè)面 監(jiān)聽(tīng)自己的hashchange
2、a頁(yè)面中的ifame b.com下的b頁(yè)面 改變parent的hash
3红淡、b.com 不能直接改變a.com 的hash時(shí) 需要引入a.com 中的c頁(yè)面#mydata
4不狮、因?yàn)閏頁(yè)面和a頁(yè)面同源 所以c頁(yè)面可以
parent.parent.location.hash = self.location.hash.substring(1);
來(lái)改變a頁(yè)面的hash
ok

4、window.name實(shí)現(xiàn)的跨域數(shù)據(jù)傳輸

function crossDomainPost() {
    // Add the iframe with a unique name
    var iframe = document.createElement("iframe");
    var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
    document.body.appendChild(iframe);
    iframe.style.display = "none";
    iframe.contentWindow.name = uniqueString;

    // construct a form with hidden inputs, targeting the iframe
    var form = document.createElement("form");
    form.target = uniqueString;
    form.action = "http://INSERT_YOUR_URL_HERE";
    form.method = "POST";

    // repeat for each parameter
    var input = document.createElement("input");
    input.type = "hidden";
    input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
    input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
    form.appendChild(input);

    document.body.appendChild(form);
    form.submit();
}

5在旱、使用HTML5 postMessage

Chrome 2.0+摇零、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+都支持這個(gè)功能

otherWindow.postMessage(message, targetOrigin);
otherWindow: 對(duì)接收信息頁(yè)面的window的引用⊥靶可以是頁(yè)面中iframe的contentWindow屬性驻仅;window.open的返回值;通過(guò)name或下標(biāo)從window.frames取到的值登渣。
message: 所要發(fā)送的數(shù)據(jù)噪服,string類型。
targetOrigin: 用于限制otherWindow胜茧,“*”表示不作限制

a.com/index.html中的代碼:
<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
    var ifr = document.getElementById('ifr');
    var targetOrigin = 'http://b.com';  // 若寫成'http://b.com/c/proxy.html'效果一樣
                                        // 若寫成'http://c.com'就不會(huì)執(zhí)行postMessage了
    ifr.contentWindow.postMessage('I was there!', targetOrigin);
};
</script>

b.com/index.html中的代碼:

<script type="text/javascript">
    window.addEventListener('message', function(event){
        // 通過(guò)origin屬性判斷消息來(lái)源地址
        if (event.origin == 'http://a.com') {
            alert(event.data);    // 彈出"I was there!"
            alert(event.source);  // 對(duì)a.com粘优、index.html中window對(duì)象的引用
                                  // 但由于同源策略,這里event.source不可以訪問(wèn)window對(duì)象
        }
    }, false);
</script>

6呻顽、利用flash

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末雹顺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子廊遍,更是在濱河造成了極大的恐慌无拗,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昧碉,死亡現(xiàn)場(chǎng)離奇詭異英染,居然都是意外死亡揽惹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門四康,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)搪搏,“玉大人,你說(shuō)我怎么就攤上這事闪金》枘纾” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵哎垦,是天一觀的道長(zhǎng)囱嫩。 經(jīng)常有香客問(wèn)我,道長(zhǎng)漏设,這世上最難降的妖魔是什么墨闲? 我笑而不...
    開(kāi)封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮郑口,結(jié)果婚禮上鸳碧,老公的妹妹穿的比我還像新娘。我一直安慰自己犬性,他們只是感情好瞻离,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著乒裆,像睡著了一般套利。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鹤耍,一...
    開(kāi)封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天日裙,我揣著相機(jī)與錄音,去河邊找鬼惰蜜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛受神,可吹牛的內(nèi)容都是我干的抛猖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鼻听,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼财著!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起撑碴,我...
    開(kāi)封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撑教,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后醉拓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體伟姐,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡收苏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愤兵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹿霸。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秆乳,靈堂內(nèi)的尸體忽然破棺而出懦鼠,到底是詐尸還是另有隱情,我是刑警寧澤屹堰,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布肛冶,位于F島的核電站,受9級(jí)特大地震影響扯键,放射性物質(zhì)發(fā)生泄漏睦袖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一忧陪、第九天 我趴在偏房一處隱蔽的房頂上張望扣泊。 院中可真熱鬧,春花似錦嘶摊、人聲如沸延蟹。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阱飘。三九已至,卻和暖如春虱颗,著一層夾襖步出監(jiān)牢的瞬間沥匈,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工忘渔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留高帖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓畦粮,卻偏偏與公主長(zhǎng)得像散址,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宣赔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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