Javascript跨域整理

在前端的JS請求中,跨域的問題經常存在,根據不同的實現原理,常見的跨域的方法如下:
一:前端的方式

1:在前端頁面中,可以直接引用跨域資源的標簽有三個,分別是img的src,style的href和script的src。這三個都可以直接引用外域的資源。
在img和style的請求中,可以直接通過請求的地址加后綴參數進行參數傳遞,但是沒有接受服務器返回的操作。
在script的src可以通過和服務器端的配合實現數據的傳遞與返回,稍后討論
2:其他前端的跨域方式
2.1:document.domain方式,同源策略,在考慮跨域問題的時候,如果兩個頁面擁有相同的主域但是子域不同,則可以通過document.domain的修改實現兩者相同域的實現。在修改的時候注意只能修改為與當前相同的域或者父級的域。而且必須是一個符合格式的domain。
2.2:window.name跨域
window對象有個name屬性,該屬性有個特征:即在一個窗口(window)的生命周期內,窗口載入的所有的頁面都是共享一個window.name的,每個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗口載入過的所有頁面中的,并不會因新頁面的載入而進行重置。
比如有一個www.domain1.com/receive.html頁面,需要通過receive.html頁面里的js來獲取另一個位于不同域上的頁面www.domain2.com/data.html里的數據。
data.html頁面里的代碼很簡單,就是給當前的window.name設置一個receive.html頁面想要得到的數據值。data.html里的代碼:

window.name="I am the data";

那么在receive.html頁面中,我們怎么把data.html頁面載入進來呢?顯然我們不能直接在a.html頁面中通過改變window.location來載入data.html頁面,因為我們想要即使receive.html頁面不跳轉也能得到data.html里的數據。答案就是在receive.html頁面中使用一個隱藏的iframe來充當一個中間人角色,由iframe去獲取data.html的數據,然后a.html再去得到iframe獲取到的數據。
充當中間人的iframe想要獲取到data.html的通過window.name設置的數據,只需要把這個iframe的src設為www.domain2.com/data.html就行了。然后a.html想要得到iframe所獲取到的數據,也就是想要得到iframe的window.name的值,還必須把這個iframe的src設成跟receive.html頁面同一個域才行,不然根據前面講的同源策略,receive.html是不能訪問到iframe里的window.name屬性的。這就是整個跨域過程。
2.3:postMessage
postMessage是Html5新增的處理跨域問題的API,postMessage(data,origin)接受兩個參數。

1.data:要傳遞的數據,html5規范中提到該參數可以是JavaScript的任意基本類型或可復制的對象,然而并不是所有瀏覽器都做到了這點兒,部分瀏覽器只能處理字符串參數,所以我們在傳遞參數的時候需要使用JSON.stringify()方法對對象參數序列化,在低版本IE中引用json2.js可以實現類似效果。

2.origin:字符串參數,指明目標窗口的源,協議+主機+端口號[+URL],URL會被忽略,所以可以不寫,這個參數是為了安全考慮,postMessage()方法只會將message傳遞給指定窗口,當然如果愿意也可以建參數設置為"*",這樣可以傳遞給任意窗口,如果要指定和當前窗口同源的話設置為"/"。

操作示例:

<div>
  <div id="color">Frame Color</div>
</div>
<div>
  <iframe id="child" src="http://domain2.com/test.html"></iframe>
</div>

在domain1中通過如下方法調用postMessage接口

window.onload=function(){
    window.frames[0].postMessage('getcolor','http://lslib.com');
}

接受的時候監聽Window的message事件:

window.addEventListener('message',function(e){
    if(e.source!=window.parent) return;
    var color=e.data;
    console.log(e.data);
}
二:后端的方式

在后端處理的過程中,服務器通過Access-Control-Allow-Origin可以設置那些域可以訪問當前資源,如果要開放給所有的域訪問,則直接設置為*即可。
優點是瀏覽器端不用考慮同源策略的限制,缺點就是增加服務器的負擔,且訪問速度慢。

三:前后端的方式

這里涉及到的就是我們經常說道的JSONP的方式,JSONP是通過前后端配合的方式實現跨域的實現,前端采用的是基于Script的實現,通過動態的創建script標簽,將要請求數據的參數和回調函數寫在src 的參數中。服務器收到請求之后,按照對應的參數和回調函數返回對應的結果,
示例如下:
假如當前我們的網站www.our.com想獲取12306的某一輛車的余票情況,我們客戶端如下構造:

function getInfoCallback(data){
    console.log(data);
}
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src="http://www.12306.com/getLeftTicket?id=k58&callback=getInfoCallback;

然后12306那邊按照我們傳遞的參數和回調函數返回如下的script內容:

getInfoCallback({
  id: "k58",
  left: 123
})

當script收到返回的內容相當于直接調用當前頁面的函數,以此可以達到跨域的功能。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內容

  • 跨域問題產生的原理是指通過js在不同的域之間進行數據傳輸或通信,比如用ajax向一個不同的域請求數據,或者通過js...
    往復隨安_cc75閱讀 522評論 0 1
  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協議...
    w_zhuan閱讀 525評論 0 0
  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協議...
    他在發呆閱讀 829評論 0 0
  • 跨域資源共享 CORS 對于web開發來講,由于瀏覽器的同源策略,我們需要經常使用一些hack的方法去跨域獲取資源...
    默默先生Alec閱讀 598評論 0 0
  • 太陽落山了,我們家鄉的農村人該燒炕咧! 燒炕的時候,先把炕眼門一拔,攬上一糞籠麥草、一糞籠衣子,或者恰...
    俺就是個俗人閱讀 486評論 0 0