同源策略
首先解釋:同源策略
同源策略是瀏覽器最核心也最基本的安全功能,這個策略可以阻止一個頁面上的惡意腳本通過頁面的DOM對象獲得訪問另一個頁面上敏感信息的權(quán)限。
同源,要求URL源的協(xié)議,域名,端口完全相同(IE在計算源的時候沒有包括端口。)
跨域方法
- jsonp實(shí)現(xiàn)跨域
- CORS跨域資源共享
- document.domain+iframe(子域名代理)
- postMessage實(shí)現(xiàn)跨域
-
通過jsonp跨域(廢棄)
JSONP(JSON with Padding)是資料格式 JSON 的一種“使用模式”,可以讓網(wǎng)頁從別的網(wǎng)域要資料。
JSONP由兩部分組成:回調(diào)函數(shù)和數(shù)據(jù)。回調(diào)函數(shù)是當(dāng)響應(yīng)到來時應(yīng)該在頁面中調(diào)用的函數(shù),而數(shù)據(jù)就是傳入回調(diào)函數(shù)中的JSON數(shù)據(jù)。
文檔中不受跨域影響的標(biāo)簽有<script><img><iframe>,jsonp是包含json數(shù)據(jù)的js函數(shù),通過放在<script>標(biāo)簽中插入DOM執(zhí)行
在js中,我們不可以直接用XMLHttpRequest請求不同域上的數(shù)據(jù),但是我們可以在頁面上引用不同域的js文件
JSONP的優(yōu)缺點(diǎn):
JSONP的優(yōu)點(diǎn)是:它不像XMLHttpRequest對象實(shí)現(xiàn)的Ajax請求那樣受到同源策略的限制;
它的兼容性更好,在更加古老的瀏覽器中都可以運(yùn)行,不需要XMLHttpRequest或ActiveX的支持;并且在請求完畢后可以通過調(diào)用callback的方式回傳結(jié)果。
JSONP的缺點(diǎn)則是:它只支持GET請求而不支持POST等其它類型的HTTP請求;
它只支持跨域HTTP請求這種情況,不能解決不同域的兩個頁面之間如何進(jìn)行JavaScript調(diào)用的問題。
-
CORS——跨域資源共享
CORS(Cross-Origin Resource Sharing)跨域資源共享,它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest2.0版請求,從而克服了AJAX只能同源使用的限制。
參考阮一峰大大的 跨域資源CORS詳解
使用"跨域資源共享"的前提,是瀏覽器必須支持這個功能,而且服務(wù)器端必須同意這種"跨域"。如果能夠滿足上面的條件,則代碼的寫法與不跨域的請求完全一樣。瀏覽器會自動在請求頭部添加origin字段,有時甚至多一次http請求,但是不會對用戶造成影響。
xhr.open('GET', 'http://other.server/and/path/to/script');
CORS與JSOP對比:
1、 JSONP只能實(shí)現(xiàn)GET請求,而CORS支持所有類型的HTTP請求
2、 使用CORS,開發(fā)者可以使用普通的XMLHttpRequest發(fā)起請求和獲得
數(shù)據(jù),比起JSONP有更好的錯誤處理。
3、 JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數(shù)現(xiàn)代瀏覽器都已經(jīng)支持了CORS,CORS更加方便、可靠
-
通過修改document.domain來跨子域
對于主域相同而子域不同的情況,可以通過設(shè)置document.domain的辦法來解決。如:對于兩個文件www.a.com/a.html和 blog.a.com/b.html均加上設(shè)置document.domain = ‘a.com’;然后在a.html文件中創(chuàng)建一個iframe,通過iframe兩個js文件即可交互數(shù)據(jù):
//www.a.com/a.html
<script>
document.doamin = 'a.com';
var iframe = document.createElement('iframe');
iframe.src = 'http://blog.a.com/b.html';
document.body.appendChild(iframe);
iframe.onload = function() {
var doc = iframe.contentDocument || iframe.contentWindow.document;
// 在這里操縱b.html
console.log(doc);
};
</script>
在blog.a.com/b.html內(nèi)編寫代碼:
//blog.a.com/b.html
<script>
document.domain = 'a.com';
</script>
備注:某一頁面的domain默認(rèn)等于window.location.hostname。主域名是不帶www的域名,例如a.com,主域名前面帶前綴的通常都為二級域名或多級域名,例如 blog.a.com其實(shí)是二級域名。 domain只能設(shè)置為主域名,不可以在blog.a.com中將domain設(shè)置為test.a.com
-
postmessage跨域