跨域

瀏覽器同源策略

瀏覽器出于安全考慮,默認情況下,只允許在本域接口下進行數據交互。這是瀏覽器的一種安全保護機制。主要限制有兩個方面:

一、不同源的文檔不能通過ajax實現請求,例如通過XHR實現Ajax通信,默認,XHR只能訪問與包含它的頁面位于同一個域中的資源,而不能訪問其他域下的資源。

二、瀏覽器中不同域的框架也是不能通過js進行交互操作。

什么是跨域?

只要協議、域名、端口號中有任何一個不相同,就算是不同的域。要實現在不同域之間進行數據交互,就需要用到跨域的技術。

對于端口號和協議不同的情況,只能通過后臺實現跨域。

跨域的幾種方式:

1、CORS(跨域資源共享Cross-Origin Resource Sharing)

定義了在必須跨域訪問的情況下,服務器和瀏覽器是如何進行溝通。cors背后的思想就是通過自定義的HTP頭部的信息的反饋,決定整個請求響應過程的成敗。

比較一下在使用cors實現跨域和沒有跨域的情況下,ajax代碼的區別:

var xhr=new XMLHttpRequest();

xhr.open('get','/loadMore?index='+pageIndex+'&length=5',true) ?// ?沒有cors ?url是一個相對路徑

xhr.send();

var ?xhr=new ?XMLHttpRequest();

xhr.open('get', 'http://baidu.com:8080/getNews', true); // cors 實現跨域 ? ?URL換成其他域的絕對地址

xhr.send();

如上使用get方法發送一個請求時,在他的頭部附加一個Origin頭部,其中包含請求頁面的源信息(協議、域名、端口)

Origin: http://baidu.com:8080

服務器根據這個頭部信息來決定是否允許響應,如果服務器認為這個請求可以接受,就會在Access-Control-Allow-Origin的頭部中回發同樣的源信息

Access-Control-Allow-Origin: http://baidu.com:8080

如果沒有這個頭部,或者源信息不匹配,瀏覽器就會駁回請求。

2、JSONP

(JSON with padding)是JSON的一種使用格式,可以讓網頁訪問其他網域下的資源,也叫填充式JSON

JSONP的特性:

html中的script標簽可以引用其他域中的文件,可實現跨域訪問。需要后端的支持與配合。

JSONP由兩部分組成:回調函數和數據; ??

回調函數就是在響應到來的時候,在頁面中調用的函數,數據就是服務器發過來的json數據

callback({"name":"sty"})

使用jsonp來實現跨域:

js文件

var script=document.createElement('script'); ?//創建script元素

script.src='http://a.jrg.com:8080/getNews?callback=appendHtml'; ?//指定要訪問的URL,其中回調函數是appendChild,用于處理數據

document.head.appendChild(script); ?//在頁面頭部添加script節點

document.head.removeChild(script); ?//在實現跨域功能后,移除script節點,保持頁面的簡潔

后端:

var cb = req.query.callback;

if(cb) {

? ? ?res.send(cb+'('+JSON.stringify(data)+')');

} else {

res.send(data);

}

JSONP的優缺點

JSONP的優點是:它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中都可以運行,不需要XMLHttpRequest或ActiveX的支持;并且在請求完畢后可以通過調用callback的方式回傳結果。

JSONP的缺點則是:它只支持GET請求而不支持POST等其它類型的HTTP請求;它只支持跨域HTTP請求這種情況,不能解決不同域的兩個頁面之間如何進行JavaScript調用的問題。

CORS和JSONP對比

1、 JSONP只能實現GET請求,而CORS支持所有類型的HTTP請求。

2、 使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得數據,比起JSONP有更好的錯誤處理。

3、 JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS)

使用JSONP實現跨域,也會存在一定的安全隱患,例如XSS攻擊

3、降域

瀏覽器中不同域的框架也是不能通過js進行交互的,但是不同框架之間可以獲取到window對象,但卻無法獲取到相應的屬性和方法。

例如? a.baidu.com 域下的一個 html 文檔里有一個在其他域下(b.baidu.com)的 iframe 框架,在a.baidu.com 中并不能訪問到 b.baidu.com 里的數據;

但可以獲取到 b.baidu.com 中的 window 對象,但是這時 window 的屬性和方法并不可用,兩個文件中使用?document.domain('baidu.com')方法?把域名都降到baidu.com;

這樣就可以在 a.baidu.com 中使用 iframe 里面的 window 的所有屬性和方法了,通過window.frames[0] 獲取到 iframe 框架,但是這時再通過window.frames[0].document.querySelector(element) 獲取到 iframe 里的 element 元素。

在b.baidu.com 中通過window.parent.document.querySelector(element) 獲取到html里的元素。

document.domain只適用于不同子域的框架之間實現跨域訪問。

主要使用document.domain()


4、postMessage

這是HTML5的一種跨域訪問資源的方法。

window.postMessage(message,targetOrigin)方法是html5新引進的特性,可以使用它來向其它的window對象發送消息,無論這個window對象是屬于同源或不同源,目前IE8+、FireFox、Chrome、Opera等瀏覽器都已經支持window.postMessage方法。

document.querySelector('.main input').addEventListener('input',function() {

console.log(this.value);

window.frames[0].postMessage(this.value,"*") ?//訪問不同源的框架的message

})

window.addEventListener('message',function(e) { ?/*在window上綁定一個監聽事件,監測message*/

document.querySelector('.main input').value=e.data//通過e.data可以監聽到別人發給我的信息

console.log(e.data);

})

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

推薦閱讀更多精彩內容

  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協議...
    w_zhuan閱讀 525評論 0 0
  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協議...
    他在發呆閱讀 829評論 0 0
  • 跨域資源共享 CORS 對于web開發來講,由于瀏覽器的同源策略,我們需要經常使用一些hack的方法去跨域獲取資源...
    默默先生Alec閱讀 598評論 0 0
  • 什么是跨域? 2.) 資源嵌入:、、、等dom標簽,還有樣式中background:url()、@font-fac...
    電影里的夢i閱讀 2,382評論 0 5
  • 羌管翩逐花影,鬧春風。倦人倚門嘆鏡心亂空。 花期負,朝與暮,盼君顧,自是君來不知奴歸處。
    徐小丸子小姐閱讀 346評論 6 3