什么是同源策略?
同源是瀏覽器出于安全方面的考慮,只允許與本域下的接口交互秒拔。不同源的客戶(hù)端腳本在沒(méi)有明確授權(quán)的情況下,不能讀寫(xiě)對(duì)方的資源砂缩。
由Netscape提出的一個(gè)著名的安全策略∪洌現(xiàn)在所有支持JavaScript 的瀏覽器都會(huì)使用這個(gè)策略
同源三大要素:,就是必須協(xié)議喳挑、域名滔悉、端口
都一致的单绑,才叫做同源
- 相同協(xié)議:如都是http或者h(yuǎn)ttps
- 相同域名:是用來(lái)定位網(wǎng)站的獨(dú)一無(wú)二的名字
http://jirengu.com/a
和http://jirengu.com/b
或者www.baidu.com
和www.baidu.cn
- 相同端口:如都是80端口,或者8080端口
看一些同源例子:
http://jirengu.com/a/b.js
和http://jirengu.com/index.php
(同源)
不同源的例子:
http://jirengu.com/main.js
和https://jirengu.com/a.php
(協(xié)議不同)
http://jirengu.com/main.js
和http://bbs.jirengu.com/a.php
(域名不同,域名必須完全相同才可以)
http://jiengu.com/main.js
和 http://jirengu.com:8080/a.php
(端口不同,第一個(gè)是80)
需要注意的是: 對(duì)于當(dāng)前頁(yè)面來(lái)說(shuō)頁(yè)面存放的 JS 文件的域不重要歉提,重要的是加載該 JS 頁(yè)面所在什么域
同源策略的目的是什么:
- 為了保證用戶(hù)信息的安全,防止惡意網(wǎng)站竊取數(shù)據(jù)
- Cookie 往往用來(lái)保存用戶(hù)的登錄狀態(tài)版扩,如果用戶(hù)沒(méi)有退出登錄,其他網(wǎng)站就可以冒充用戶(hù)礁芦,為所欲為悼尾。因?yàn)闉g覽器同時(shí)還規(guī)定,提交表單不受同源政策的限制未状。
- 所以同源策略非常重要,不然cookie可以共享司草,互聯(lián)網(wǎng)沒(méi)有安全可言泡仗。
限制范圍
- 非同源:
Cookie(window.domain)
-
DOM無(wú)法獲取(iframe和window.open打開(kāi)的窗口)
(window.domain)(window.postMessage) -
AJAX
請(qǐng)求不能發(fā)送
如何規(guī)避這些限制呢??
規(guī)避限制一: cookie
- cookie是服務(wù)器寫(xiě)入瀏覽器的一段信息吨岭,只有同源的可以共享,網(wǎng)站要求用戶(hù)登入自己的賬戶(hù),登入后辣辫,認(rèn)證接口就會(huì)下發(fā)給瀏覽器一個(gè)cookie,通過(guò)
document.domain
Set-Cookie: key=value; domain=.example.com; path=/
完成了cookie的植入急灭,通過(guò)這種策略就完成了網(wǎng)站的統(tǒng)一認(rèn)證登入谷遂,這個(gè)在cookie中就會(huì)有一個(gè)相對(duì)比較重要的cookie參數(shù)
規(guī)避限制二: iframe
如果兩個(gè)網(wǎng)頁(yè)不同源,就無(wú)法拿到對(duì)方的DOM畴嘶。
解決方法:
片段識(shí)別符(fragment identifier)
window.name
跨文檔通信API(Cross-document messaging)
限制規(guī)避三: Ajax
- JSONP是服務(wù)器與客戶(hù)端跨源通信的常用方法集晚。最大特點(diǎn)就是簡(jiǎn)單適用,老式瀏覽器全部支持偷拔,服務(wù)器改造非常小亏钩。
它的基本思想是欺旧,網(wǎng)頁(yè)通過(guò)添加一個(gè)<script>元素,向服務(wù)器請(qǐng)求JSON數(shù)據(jù)栅哀,這種做法不受同源政策限制踏枣;服務(wù)器收到請(qǐng)求后,將數(shù)據(jù)放在一個(gè)指定名字的回調(diào)函數(shù)里傳回來(lái)茵瀑。 - WebSocket是一種通信協(xié)議,使用ws://(非加密)和wss://(加密)作為協(xié)議前綴马昨。該協(xié)議不實(shí)行同源政策,只要服務(wù)器支持屹篓,就可以通過(guò)它進(jìn)行跨源通信匙奴。
- CORS這個(gè)是現(xiàn)在用到比較廣的一種方式,全稱(chēng)是”跨域資源共享”泼菌。
后面重點(diǎn)講解ajax的不同源解決方案
什么是跨域?跨域有幾種實(shí)現(xiàn)形式
先了解一下什么是跨域
跨域就是允許不同域的接口進(jìn)行交互荒揣,說(shuō)白點(diǎn)就是post焊刹、get的url不是你當(dāng)前的網(wǎng)站,域名不同虐块。
- 跨域的幾種方式:
- JSONP
- CORS
- 降域
- postMessage
JSONP 的原理是什么
- 自動(dòng)跨域的前提是服務(wù)端愿意提供接口給你用,
- 利用了
javascript
可以加載一個(gè)東西,不受同源策略的限制,相當(dāng)于可以加載任意的東西作為js
來(lái)執(zhí)行,但需要后端來(lái)支持 - 數(shù)據(jù)來(lái)了以后,我們自己寫(xiě)好了一個(gè)函數(shù)來(lái)操作這些數(shù)據(jù),最后在src后面加上最后加個(gè)參數(shù)
callback=_fun(函數(shù)名)
專(zhuān)業(yè)總結(jié)就是
- 定義數(shù)據(jù)處理函數(shù)_fun
- 創(chuàng)建script標(biāo)簽,src的地址執(zhí)行后端接口举农,最后加個(gè)參數(shù)callback=_fun
- 服務(wù)端在收到請(qǐng)求后敞嗡,解析參數(shù),計(jì)算返還數(shù)據(jù)喉悴,輸出 fun(data) 字符串。
- fun(data)會(huì)放到script標(biāo)簽做為js執(zhí)行婚脱。此時(shí)會(huì)調(diào)用fun函數(shù)勺像,將data做為參數(shù)。
CORS是什么
-
CORS 全稱(chēng)是跨域資源共享(Cross-Origin Resource Sharing)
,是一種 ajax 跨域請(qǐng)求資源的方式殃姓,支持現(xiàn)代瀏覽器,IE支持10以上蜗侈。 實(shí)現(xiàn)方式很簡(jiǎn)單,當(dāng)你使用 XMLHttpRequest 發(fā)送請(qǐng)求時(shí)枷颊,瀏覽器發(fā)現(xiàn)該請(qǐng)求不符合同源策略,會(huì)給該請(qǐng)求加一個(gè)請(qǐng)求頭:Origin夭苗,后臺(tái)進(jìn)行一系列處理吆倦,如果確定接受請(qǐng)求則在返回結(jié)果中加入一個(gè)響應(yīng)頭:Access-Control-Allow-Origin; 瀏覽器判斷該相應(yīng)頭中是否包含 Origin 的值,如果有則瀏覽器會(huì)處理響應(yīng)蚕泽,我們就可以拿到響應(yīng)數(shù)據(jù),如果不包含瀏覽器直接駁回须妻,這時(shí)我們無(wú)法拿到響應(yīng)數(shù)據(jù)。所以 CORS 的表象是讓你覺(jué)得它與同源的 ajax 請(qǐng)求沒(méi)啥區(qū)別敛惊,代碼完全一樣。
- 需要修改
hosts
文件
降域
降域其實(shí)是吧域名降一個(gè)等級(jí)
document.domain
postMessage
-
postMessage
的原理是會(huì)向另一個(gè)地方發(fā)送信息瞧挤,另一個(gè)地方通常是iframe,或者是由當(dāng)前頁(yè)面彈出的窗口。參數(shù)是:信息以及表示接受消息方的來(lái)自哪個(gè)域的字符串执俩,如果給定*便是不限定接受者的域。
所以在一個(gè)html中嵌入另一個(gè)html文件的iframe役首,并且互相發(fā)送postMessage并響應(yīng)在input框以此來(lái)觀察效果显拜。