從原理分析CORS——咱們究竟是怎麼跨域的

同源策略相信各位同窗已然不陌生了,在這裏不作過多闡述,簡單介紹一下就好:php

URL 說明 是否容許
http://www.a.com/a.js / http://www.a.com/b.js 同一域名下 容許
http://www.a.com/lab/a.js / http://www.a.com/script/b.js 同一域名下不一樣文件夾 容許
http://www.a.com:8000/a.js http://www.a.com/b.js 同一域名,不一樣端口 不容許
http://www.a.com/a.js https://www.a.com/b.js 同一域名,不一樣協議 不容許
http://www.a.com/a.js http://70.32.92.74/b.js 域名和域名對應ip 不容許
http://www.a.com/a.js http://script.a.com/b.js 主域相同,子域不一樣 不容許
http://www.a.com/a.js http://a.com/b.js 同一域名,不一樣二級域名(同上) 不容許(cookie這種狀況下也不容許訪問)
http://www.cnblogs.com/a.js http://www.a.com/b.js 不一樣域名 不容許

以上表格系統的闡述瞭如何算是跨域。json

那麼下面咱們
今天咱們着重講講對抗同源策略的方法:
CORS——Cross-origin resource sharing(跨來源資源共享)跨域

因爲HTML 5的概念造成,在原有XHR的基礎上提出了XMLHttpRequest Level2(XHR2),在XHR2中對CORS有了很好的支持。(除了遠古的IE8,IE9這些老古董)瀏覽器

咱們先看看看CORS平常是怎麼實現跨域的服務器

• <?php  
•  /*
•  這裏是簡單的一個CORS Demo
•  */
• //經過請求體獲取$_POST的name,gender
• $ret = array(  
•     'name' => isset($_POST['name'])? $_POST['name'] : '',  
•     'gender' => isset($_POST['gender'])? $_POST['gender'] : ''  
• );  
•   
• //HTTP_ORIGIN是請求頭中的信息,在瀏覽器中直接展現爲Origin
• $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';  
• //此處是容許跨域的白名單
• $allow_origin = array(  
•     'http://www.client.com',  
•     'http://www.client2.com'  
• );  
• //判斷當前Origin來源是否在白名單內,是的話就容許設置一套三式Header頭讓他跨域  
• if(in_array($origin, $allow_origin)){ 
•      //關鍵點是這裏的一套三式 
•     header('Access-Control-Allow-Origin:'.$origin);  //容許的域名
•     header('Access-Control-Allow-Methods:POST');  //容許的方法
•     header('Access-Control-Allow-Headers:x-requested-with,content-type');  //服務器支持的頭信息
• }  
•   
• echo json_encode($ret);  
• ?> 

關鍵詞在header('Access-Control-Allow-*':) 一套三件,不一樣若是沒法經過這一套三件的洗禮,那麼就報相似下面這樣的錯:cookie

XMLHttpRequest cannot load http://b.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.com' is therefore not allowed access.

這個就是瀏覽器同源策略形成的,若是咱們沒有設置Header頭三件套的話('Access-Control-Allow-*':)那麼對一切跨域請求操做瀏覽器都是拒絕的~。測試

可是隨着互聯網的發展,同源策略嚴重影響了項目之間的鏈接(尤爲是大項目,有幾個域名須要進行溝通的),W3C標準推出了「跨來源資源共享——CORS」。code

回到前面的那段實例代碼,咱們來分析分析 請求-》處理-》返回 一套流程的前因後果。blog

CORS的背後基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求響應是應該成功仍是應該失敗。
當Http請求發起(能夠經過更新操做去測試POST,或者用JavaScript請求測試GET)的時候(不分跨不跨域)會相似帶着如下請求頭信息:ip

Origin:http://www.csdnblog.com

返回頭也會夾帶着相似以下信息:

Access-Control-Allow-Credentials:true 
Access-Control-Allow-Origin:http://www.csdnblog.com

一來一回的請求決定的請求決定了改請求是否會被瀏覽器經過,若是返回頭中沒有這個頭部,或者有頭部可是源信息不匹配(就是說返回頭%-Allow-Origin中沒有當前請求站點的域名),那麼瀏覽器就會幫咱們駁回此次請求,同源策略在這裏發揮了做用。

經過這一來一回咱們不難發現其實瀏覽器判斷是否駁回的標準就是返回頭中是否有 Access-Control-Allow-% 這個信息,而且判斷這個信息是否合法(即這個信息是不是與請求頭中的Origin對應的上),對應的上就經過,對應不上就駁回。

既然搞懂這個咱們就能夠理解爲什麼經過CORS設置兩三行Header代碼既能夠輕鬆跨域了吧?

服務端代碼設置Header返回頭告訴瀏覽器「誰誰誰是容許訪問個人,你看到這傢伙就給我放行吧~「。

因此若是在服務端代碼中設置:

header('Access-Control-Allow-Origin:*')

是的,這樣的話任何域名均可以請求你的服務器了,固然這樣子你的服務器也就很是危險了。

相關文章
相關標籤/搜索