危害
沒有同源策略會(huì)怎樣呢?我們可以從一個(gè)日常的購物場(chǎng)景聊起。
小明登錄一個(gè)中小購物網(wǎng)站,這個(gè)網(wǎng)站不是阿里或京東大型網(wǎng)站,一般大型網(wǎng)站不會(huì)出現(xiàn)這類問題。假設(shè)這個(gè)網(wǎng)站的域名為www.chaoshi.com,小明可以在這個(gè)網(wǎng)站購買貨品,也能查詢購物車列表。當(dāng)小明登錄到www.chaoshi.com,他個(gè)人可以查詢購物車列表的信息如鞋子、衣服、書籍,或充氣娃娃類的信息,小明的購物車當(dāng)然只能有小明看到。
這個(gè)時(shí)候www.chaoshi.com這個(gè)網(wǎng)站,有個(gè)飄來飄去的橘紅色黑客彈窗,彈窗上面充滿誘惑的文字和圖片促使小明點(diǎn)擊了一下。
當(dāng)點(diǎn)擊這個(gè)彈窗后,小明就被引導(dǎo)到了另一個(gè)網(wǎng)站,這個(gè)黑客網(wǎng)站就以www.hack.com為例。當(dāng)小明跳到黑客網(wǎng)站后,他在www.chaoshi.com的cookie信息也就被帶到了www.hack.com上。假如這個(gè)cookie里包含了小明的帳號(hào)和密碼。那www.hack.com里面的惡意黑客腳本,就可以請(qǐng)求www.chaoshi.com的信息,而且這個(gè)請(qǐng)求鏈接中會(huì)攜帶cookie中的用戶信息,所以就繞過了www.chaoshi.com的驗(yàn)證。
后面就是可怕的事情了,小明購物車的所有信息都被黑客腳本拿到了,也可以在www.hack.com顯示,然后大家都知道小明買了充氣娃娃。

比較貼切的例子就是,一個(gè)源表示是一個(gè)家庭,在這個(gè)家庭的內(nèi)部成員可以看到自己家庭內(nèi)部的信息,如家里的家具、墻上的藝術(shù)照等等。而這個(gè)家庭外的成員,如隔壁老王他就是源外的。他是不能看到這個(gè)家里的信息的。如果沒有同源策略的保護(hù),你到了老王家里一趟,后續(xù)老王就可以看到你家里的信息,這個(gè)是多么可怕的事情。
引入
為了避免這個(gè)問題出現(xiàn),1995年的網(wǎng)景瀏覽器提到同源策略,且其他瀏覽器也要支持這個(gè)約定。因此這個(gè)約定是對(duì)瀏覽器的限制,如果不是在瀏覽器發(fā)起請(qǐng)求,則這個(gè)策略就失效了。了解這個(gè)同源策略,我們從兩個(gè)問題開始:
[if !supportLists]l? [endif]同源策略有哪些角色參與?
對(duì)于一個(gè)網(wǎng)站的頁面而言,它包含兩類:一個(gè)是html的元素,如按鈕、文本、列表信息(上圖的購物車列表);另一個(gè)就是有處理邏輯的js腳本,js腳本可以讀取html的元素,如上圖的黑客腳本。

html模塊就是頁面上花花綠綠的東西,看起來比較炫的。而Js腳本則是處理邏輯模塊,它是對(duì)html模塊進(jìn)行邏輯處理,如決定從后臺(tái)Web服務(wù)器取出信息,并顯示到某個(gè)Html模塊上,或把某個(gè)Html模塊的信息提交到Web服務(wù)器。
同源策略的描述:就是只有Js腳本和Html模塊必須在同一個(gè)源下,Js腳本才能讀取或處理Html模塊。如果Js腳本在另一個(gè)源,如域名www.hack.com,則這個(gè)Js腳本不能讀取別域名下如www.chaoshi.com的Html模塊>
同源策略條件是什么?
簡(jiǎn)單說滿足三個(gè)條件:協(xié)議、域名、端口才算是同源。下面的表格給出了與URL"http://www.chaoshi.com/dir/page.html"的對(duì)比。

????如何判斷兩個(gè)url是否同源呢?其實(shí)也就是一句話,如果兩個(gè)url他們從http開始到端口這一段字符串如果都完全相等,則這兩個(gè)url就屬于同源的。例如:
A_url =?http://chaoshi.com:8080/son1/xxxx
B_url =?http://chaoshi.com:8080/son2/yy
對(duì)于A_url和B_url,它們標(biāo)粗部分都相等,則這兩個(gè)url屬于同源。對(duì)于非同源的容易當(dāng)成同源的有兩種情況:
a)兩個(gè)url域名屬于父子關(guān)系,例如父域名:http://chaoshi.com:8080/son1/xxxx,子域名:http://son.chaoshi.com:8080/son1/xxxx。那父域名和子域名不是同源
b)兩個(gè)url一個(gè)是http的,一個(gè)是https的。如http://chaoshi.com:8080/son1/xxxx和https://chaoshi.com:8080/son1/xxxx,他倆也不是同源的
3、規(guī)避
對(duì)于同源策略確實(shí)能較好保護(hù)了自己域名的信息,不能被外域名的Js腳本讀取,這個(gè)安全保護(hù)了大部分用戶的信息不被暴露。但是這個(gè)策略也有擴(kuò)大化的弊端,它不但防了域外的黑客,也防了自已人。尤其對(duì)于父子域名面言更為突出,因?yàn)樽佑蛎透赣蛎膊粚儆谕粋€(gè)源,他們倆同樣不能互相訪問。而對(duì)于實(shí)際場(chǎng)景,一個(gè)公司主體對(duì)外會(huì)只有一個(gè)web站點(diǎn),而這個(gè)站點(diǎn)上部署自己多個(gè)業(yè)務(wù)。以淘寶這個(gè)web站點(diǎn)為例,它這個(gè)站點(diǎn)可以放置阿里巴巴多個(gè)業(yè)務(wù),如下圖所示

這個(gè)站點(diǎn)就放置了“天貓”、“聚劃算”、“天貓超市”、“淘搶購”等等各個(gè)業(yè)務(wù)模塊。而這些模塊由于訪問量級(jí)、交易規(guī)模的不同,實(shí)際部署就應(yīng)該以不同的域名區(qū)分的,按同源策略的規(guī)定,“天貓”和“聚劃算”屬于不同的源,它們直接不能互相訪問,但是對(duì)同一個(gè)公司而言,有些數(shù)據(jù)資源如用戶帳號(hào)信息是應(yīng)該共享的,但是由于同源策略的限制,導(dǎo)致這些數(shù)據(jù)不能互通。
為了解決同源策略的問題,有多個(gè)規(guī)避方法可以使用,每個(gè)方案其實(shí)都有自己適合的場(chǎng)景
3.1 文檔域設(shè)置
通過把兩個(gè)域名文檔的域名document.domian設(shè)置成一致,從而實(shí)現(xiàn)兩個(gè)文檔的相互訪問,如下圖所示:

此方案適用于兩個(gè)都是子域名的文檔資源共享,而且只是少數(shù)個(gè)別文檔需要相互訪問才行。如果全部文檔都需要訪問,那就得把所有的document.domian都設(shè)置為www.chaoshi.com。這個(gè)做法不正規(guī),畢竟子域名的domain是www.a.chaoshi.com和www.b.chaoshi.com,強(qiáng)制把子域名子域名設(shè)置為父域名也不合適。而且,一旦一個(gè)域名受到攻擊,則另一個(gè)也會(huì)受到攻擊
3.2 Cors標(biāo)準(zhǔn)
Cors也即Cross-Origin Resource Sharing,為W3C提供了跨域請(qǐng)求的標(biāo)準(zhǔn)方案。IE8、Firefox 3.5 及其以后的版本、Chrome瀏覽器、Safari 4 等已經(jīng)實(shí)現(xiàn)了 Cross-Origin Resource Sharing 規(guī)范,實(shí)現(xiàn)了跨域請(qǐng)求。
簡(jiǎn)單描述為:在服務(wù)器響應(yīng)客戶端的時(shí)候,帶上Access-Control-Allow-Origin頭信息。
如果設(shè)置 Access-Control-Allow-Origin:*,則允許所有域名的腳本訪問該資源。
Access-Control-Allow-Origin:http://www.chaoshi.com,允許特定的域名訪問。具體如下圖所示:
