31.同源策略腕够、跨域倦逐、jsonp

問答

1.什么是同源策略

①源(orgin)的定義

  • 以百度為例晓避,輸入localtion.origin就可以得到源


    Paste_Image.png
  • 源包括協(xié)議交排,域名也切,端口號扑媚。如https://www.baidu.com/,它的協(xié)議是https;域名為www.baidu,com;默認(rèn)的端口為443,所以可以省略雷恃,類似的還有http協(xié)議的默認(rèn)端口為80;ftp(文本傳輸協(xié)議)的默認(rèn)端口為21

②同源策略

  • 同源策略是瀏覽器的一個功能疆股,如果瀏覽器有bug就有可能不支持。
  • 同源是指域名倒槐,協(xié)議旬痹,端口相同,比如http://jirengu.com/a/b.jshttp://jirengu.com/index.php (同源)
  • 同源策略的意思是只有同源的客戶端腳本比如js讨越,才可以讀寫對方的資源两残;
    不同源的客戶端腳本在沒有明確授權(quán)的情況下,不能讀寫對方的資源把跨。比如a.com下的js不能讀取b.com下的資源
  • 不同源的例子:
    http://jirengu.com/main.jshttps://jirengu.com/a.php(協(xié)議不同)
    http://jirengu.com/main.jshttp://bbs.jirengu.com/a.php(域名不同人弓,域名必須完全相同才可以)
    http://jiengu.com/main.jshttp://jirengu.com:8080/a.php (端口不同,第一個是80)

注意

  • 對于當(dāng)前頁面來說頁面存放的JS 文件的域不重要,重要的是加載該 JS 頁面所在什么域着逐。比如<script>標(biāo)簽引用了來源于不同地方http://www.artech.comhttp://www.jinnan.me/的兩個JavaScript腳本票从,它們均與當(dāng)前頁面同源
  1: <script src="http://www.artech.com/scripts/common.js"></script>
  2: <script src="http://www.jinnan.me/scripts/utility.js"></script>
  • 除了<script>標(biāo)簽,HTML還具有其它一些具有src屬性的標(biāo)簽,比如<img>滨嘱、<iframe><link>等,它們均具有跨域加載資源的能力浸间,所以同源策略對它們不做限制太雨。
    對于這些具有src屬性的HTML標(biāo)簽來說,標(biāo)簽的每次加載都意味著針對目標(biāo)地址的一次HTTP-GET請求魁蒜。

  • 同源策略以及跨域資源共享在大部分情況下針對的是Ajax請求囊扳。同源策略主要限制了通過XMLHttpRequest實(shí)現(xiàn)的Ajax請求,如果請求的是一個“異源”地址兜看,瀏覽器將不允許讀取返回的內(nèi)容

2.什么是跨域锥咸?跨域有幾種實(shí)現(xiàn)形式

跨域:只要協(xié)議、域名细移、端口有任何一個不同搏予,都被當(dāng)作是不同的域。為了突破同源策略的限制弧轧,跨域是指從一個網(wǎng)頁去請求另一個不同域的網(wǎng)頁的資源雪侥。
跨域?qū)崿F(xiàn)形式:
1.降域:
對于主域相同而子域不同的例子碗殷,通過設(shè)置document.domain和iframe。
比如:可以在http://child1.a.com/a.htmlhttp://child2.a.com/b.html兩個文件中分別加上document.domain = ‘a(chǎn).com’速缨;然后通過a.html文件中創(chuàng)建一個iframe锌妻,去控制iframe的contentDocument,這樣兩個js文件之間就可以“交互”了.
2.jsonp(json with padding)
由于直接用 XMLHttpRequest 請求不同域上的數(shù)據(jù)是不可以的旬牲。這種方式主要是通過動態(tài)插入一個 script 標(biāo)簽仿粹。瀏覽器對 script 的資源引用沒有同源限制,同時資源加載到頁面后會立即執(zhí)行(沒有阻塞的情況下) 原茅。但只支持get請求吭历,安全性不高
3.CORS(Cross-Origin Resource Sharing):
CORS 全稱是跨域資源共享(Cross-Origin Resource Sharing),是一種 ajax 跨域請求資源的方式员咽,支持現(xiàn)代瀏覽器毒涧,IE支持10以上。

實(shí)現(xiàn)方式很簡單贝室,當(dāng)你使用 XMLHttpRequest 發(fā)送請求時契讲,瀏覽器發(fā)現(xiàn)該請求不符合同源策略,會給該請求加一個請求頭: Origin 滑频,后臺進(jìn)行一系列處理捡偏,如果確定接受請求則在返回結(jié)果中加入一個響應(yīng)頭: Access-Control-Allow-Origin ; 瀏覽器判斷該相應(yīng)頭中是否包含 Origin 的值,如果有則瀏覽器會處理響應(yīng)峡迷,我們就可以拿到響應(yīng)數(shù)據(jù)银伟,如果不包含瀏覽器直接駁回,這時我們無法拿到響應(yīng)數(shù)據(jù)绘搞。
4.HTML5 postMessage
即跨文檔消息傳輸彤避,通過postMessage方法指明需要傳遞的數(shù)據(jù),以及目標(biāo)域名夯辖,接收端添加事件監(jiān)聽message琉预,通過事件的origin屬性判斷發(fā)送請求的域名,符合要求就接收數(shù)據(jù)蒿褂,客戶端的方法和服務(wù)端的監(jiān)聽必須配套使用圆米。
**5.其他Hack(利用hash、利用window.name) **
利用iframe和location.hash和window.name實(shí)現(xiàn)的跨域數(shù)據(jù)傳輸?shù)?br> 同源策略&跨域請求
JavaScript跨域總結(jié)與解決辦法

3.jsonp 的原理是什么

原理是利用script標(biāo)簽的可跨域性啄栓,在網(wǎng)頁中動態(tài)的創(chuàng)建并添加script標(biāo)簽娄帖,然后在請求頁面的url上添加一個callback函數(shù)名作為參數(shù)。后臺服務(wù)器將數(shù)據(jù)放在一個指定名字的callback函數(shù)給傳回來昙楚,由于網(wǎng)頁已經(jīng)定義的callback函數(shù)近速,參數(shù)被返回后,便會立即執(zhí)行。

4.CORS是什么

  • CORS需要瀏覽器和服務(wù)器同時支持数焊。目前永淌,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10佩耳;
  • 瀏覽器一旦發(fā)現(xiàn)AJAX請求跨源遂蛀,就會自動添加一些附加的頭信息——origin字段,告訴跨域的后臺這次跨域請求是由哪個源發(fā)出的
  • 實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器干厚。只要服務(wù)器實(shí)現(xiàn)了CORS接口李滴,就可以跨源通信。服務(wù)器根據(jù)前端發(fā)過來的跨域的ajax請求的origin字段蛮瞄,決定是否同意這次的跨域訪問所坯;后臺可以通過設(shè)置一個標(biāo)頭決定是否通信
  • 例如:假設(shè)我們現(xiàn)在需要從http://www.test1.comhttp://www.test2.com請求提取數(shù)據(jù),而JSONP只支持GET方法挂捅,這時候CORS就可以成為我們的選擇芹助。
    利用CORS,http://www.test2.com只需要添加一個標(biāo)頭,就可以允許來自http://www.test1.com的請求闲先。在PHP中的header()設(shè)置:
header("Access-Control-Allow-Origin:*"); 
//*表示允許任何域向我們的服務(wù)端提交需求
header("Access-Control-Allow-Origin:http://www.test1.com") 
//這樣就允許來自http://www.test1.com的需求了

跨資源共享 CORS 詳解

代碼

1.本地搭建服務(wù)器状土,演示同源策略

本地搭建服務(wù)器(如果使用 SAE 可創(chuàng)建不同的代碼版本,這樣可通過1.xxx.sinapp.com2.xxx.sinapp.com訪問了)伺糠。 修改 本地host蒙谓,通過不同域名訪問本地服務(wù)器。比如訪問http://a.com/index.html, http://b.com/ajax.php训桶,本質(zhì)是 在 index.html 里使用 ajax 接口訪問 http://b.com/ajax.php 里的數(shù)據(jù)累驮,查看輸出報錯

1.第一步,找到hosts文件


Paste_Image.png

2.第二部舵揭,打開hosts谤专。然后給本地默認(rèn)IP 127.0.0.1 綁定幾個域名,用于測試


Paste_Image.png

4.第三步午绳,用a.com/origin.html下的ajax給b.com/origin.php發(fā)請求毒租,看跨域的時候數(shù)據(jù)能否從b.com發(fā)過來。
①origin.html代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Examples</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
  <div>a.com 頁面</div>
  <script>
    $.get('//b.com/origin.php',function(response){
        console.log(response);
    })
  </script> 
</body>
</html>

②origin.php代碼

<?php
    echo 1234;
?>

③測試結(jié)果


Paste_Image.png

2.至少使用一種方式解決跨域問題

1.jsonp方式

//  a.com/origin.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Examples</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
  <div>a.com 頁面</div>

  <script>
    function xxx(data){
      alert(data);
    };
    var script=document.createElement('script');//添加動態(tài)腳本
    script.src="http://b.com/origin.php?callback=xxx"; //此處callback的值箱叁,與上面xxx函數(shù)名要一致
    document.body.appendChild(script);
  </script> 
</body>
</html>
// b.com/origin.php
<?php
    $data=$_GET['callback'];
    echo $data .'('. 123 .')';
?>

打印結(jié)果:

Paste_Image.png

2.CORS的方式

//  a.com/origin.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Examples</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
  <div>a.com 頁面</div>

  <script>
    $.get('//b.com/origin.php',function(response){
      alert(response);
    })

  </script>
</body>
</html>
//  b.com/origin.php
//在origin.php文件內(nèi),設(shè)置標(biāo)頭惕医,以及要傳輸?shù)臄?shù)據(jù):
<?php
    header("Access-Control-Allow-Origin:http://a.com");
    echo '數(shù)據(jù)獲取成功';
?>

打印結(jié)果:

Paste_Image.png


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耕漱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子抬伺,更是在濱河造成了極大的恐慌螟够,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妓笙,居然都是意外死亡若河,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門寞宫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萧福,“玉大人,你說我怎么就攤上這事辈赋■耆蹋” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵钥屈,是天一觀的道長悟民。 經(jīng)常有香客問我,道長篷就,這世上最難降的妖魔是什么射亏? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮竭业,結(jié)果婚禮上智润,老公的妹妹穿的比我還像新娘。我一直安慰自己永品,他們只是感情好做鹰,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鼎姐,像睡著了一般钾麸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炕桨,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天饭尝,我揣著相機(jī)與錄音,去河邊找鬼献宫。 笑死钥平,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的姊途。 我是一名探鬼主播涉瘾,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼捷兰!你這毒婦竟也來了立叛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤贡茅,失蹤者是張志新(化名)和其女友劉穎秘蛇,沒想到半個月后其做,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赁还,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年妖泄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艘策。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹈胡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柬焕,到底是詐尸還是另有隱情审残,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布斑举,位于F島的核電站搅轿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏富玷。R本人自食惡果不足惜璧坟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赎懦。 院中可真熱鬧雀鹃,春花似錦、人聲如沸励两。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽当悔。三九已至傅瞻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盲憎,已是汗流浹背嗅骄。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饼疙,地道東北人溺森。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像窑眯,于是被迫代替她去往敵國和親屏积。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

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