摘要:三哪些會(huì)受到同源策略限制對(duì)于瀏覽器來(lái)說(shuō),除了會(huì)受到同源策略的限制外,瀏覽器加載的一些第三方插件也有各自的同源策略。九的現(xiàn)代瀏覽器允許腳本直連一個(gè)地址而不管同源策略。
一、Origin(源)
源由下面三個(gè)部分組成:
域名
端口
協(xié)議
兩個(gè) URL ,只有這三個(gè)都相同的情況下,才可以稱為同源。
下來(lái)就以 "http://www.example.com/page.html" 這個(gè)鏈接來(lái)比較說(shuō)明:
對(duì)比URL | 結(jié)果 | 原因 |
---|---|---|
http://m.example.com/page.html | 不同源 | 域名不同 |
https://www.example.com/page.... | 不同源 | 協(xié)議不同 |
http://www.example.com:8080/page.html | 不同源 | 端口不同 |
http://www.example.com/page3.... | 同源 | 同域名,同端口,同協(xié)議 |
瀏覽器的同源策略是一種安全功能,同源策略限制了從同一個(gè)源加載的文檔或腳本如何與來(lái)自另一個(gè)源的資源進(jìn)行交互。這是一個(gè)用于隔離潛在惡意文件的重要安全機(jī)制。所以a.com下的js腳本采用ajax讀取b.com里面的文件數(shù)據(jù)是會(huì)報(bào)錯(cuò)的。
三、哪些會(huì)受到同源策略限制對(duì)于瀏覽器來(lái)說(shuō),除了DOM、Cookie、XMLHttpRequest 會(huì)受到同源策略的限制外,瀏覽器加載的一些第三方插件也有各自的同源策略。最常見的一些插件如 Flash ,有自己的控制策略。
所以,想要體驗(yàn)下,同源策略限制,你就可以寫一個(gè)ajax 請(qǐng)求,比如127.0.0.1:80 要請(qǐng)求127.0.0.1:8080 的 a.js ;
127.0.0.1:80 里的index.html
Document 另一個(gè)頁(yè)面
然后就會(huì)報(bào)錯(cuò)了,出現(xiàn)了同源策略限制了。
四、什么是跨域呢說(shuō)的跨域,其實(shí)呢就是跨源。而跨域是一個(gè)統(tǒng)稱,通過(guò)上面的我們知道了,因?yàn)橥床呗?,不同源之間,不能進(jìn)行交互。那么跨域就是解決不同源之間發(fā)起請(qǐng)求、請(qǐng)求數(shù)據(jù)、發(fā)送數(shù)據(jù)、通信等交互問(wèn)題解決方法的統(tǒng)稱。
在瀏覽器中,、 、、、 等標(biāo)簽都可以跨域加載資源,而不受同源策略的限制,通過(guò) src 屬性加載的資源,瀏覽器都會(huì)發(fā)起一個(gè) GET 請(qǐng)求,但是瀏覽器限制了 JavaScript 的權(quán)限,使用js不能讀、寫加載的內(nèi)容。
這句話什么意思呢,其實(shí)就是,你可以通過(guò)這幾個(gè)標(biāo)簽來(lái)跨域加載資源,但是,發(fā)起的GET請(qǐng)求 返回的數(shù)據(jù),通過(guò) js 獲取不到。
注意:通過(guò) 標(biāo)簽獲取 js 文件里的全局屬性,方法等,可以通過(guò) js 讀取到。是因?yàn)檫@些都是掛載在 window對(duì)象上的,看下面:
127.0.0.1 index.html
Document
127.0.0.1:8080 index.js
function say(){ var app = document.getElementById("app"); app.innerHTML = "我是被掛載到window對(duì)象上的方法,所以可以獲取到我!"; }五、jsonp跨域
到底什么是jsonp 跨域呢?其實(shí),jsonp 跟 json 兩者沒(méi)有什么關(guān)系,也沒(méi)有什么相似的地方,大家都知道json 是一種數(shù)據(jù)格式,而jsonp 之所以被稱為jsonp,我認(rèn)為跟它發(fā)出請(qǐng)求后,一般得到的,都是json格式數(shù)據(jù)有關(guān)吧。
上面說(shuō)過(guò)了,、 、、、這些標(biāo)簽都可以發(fā)起跨域請(qǐng)求,其中的 標(biāo)簽都熟悉吧,經(jīng)常用來(lái)加載 js 文件。jsonp就是利用了這個(gè)標(biāo)簽。
不知道大家有沒(méi)有疑問(wèn)啊,既然這些標(biāo)簽都能發(fā)起跨域請(qǐng)求,那么為啥只用 標(biāo)簽可以請(qǐng)求到數(shù)據(jù)呢?其實(shí)呢,關(guān)鍵就在于,再請(qǐng)求得到數(shù)據(jù)后,遇到j(luò)s代碼,就會(huì)解析執(zhí)行。理解這個(gè)也不難,你在js文件里寫的代碼,肯定是要被執(zhí)行的。
比如127.0.0.1 里的index.html 頁(yè)面加載了一個(gè) :
function say(){ console.log("666"); } say();
當(dāng)打開127.0.0.1/index.html頁(yè)面時(shí),標(biāo)簽發(fā)起了一個(gè)對(duì)index.js 的 GET 請(qǐng)求,得到數(shù)據(jù)后,js引擎開始解析執(zhí)行,然后say方法就被執(zhí)行了,這時(shí),控制臺(tái)就會(huì)輸出 "666";
那么jsonp就是利用了這點(diǎn)了。先來(lái)寫一個(gè)jsonp實(shí)例吧。
127.0.0.1 jsonp.html:
Document JSONP
然后是 127.0.0.1:8080 index.php文件:
"zdx", "sex" => "man", "age" => 18 ); $callback = $_GET["callback"]; echo $callback . "(" . json_encode($data) . ")"; ?>
當(dāng)訪問(wèn)jsonp.html時(shí),其中的發(fā)起一個(gè)請(qǐng)求,并發(fā)送了一個(gè)名為callback參數(shù),值為字符串"say"。然后index.php 把傳進(jìn)來(lái)的 say 和要發(fā)送的 data 進(jìn)行字符串拼接,json_encode 函數(shù)就是把 數(shù)據(jù)轉(zhuǎn)成json 格式的。然后這個(gè)請(qǐng)求就返回了:say({"name":"zdx","sex":"man","age":18});然后 得到這個(gè)數(shù)據(jù)后,就會(huì)解析執(zhí)行 say 函數(shù)了。
所以明白了吧,jsonp 是需要后端 支持的,需要配套使用,然后關(guān)于jsonp 是存在安全風(fēng)險(xiǎn)的,傳過(guò)來(lái)的數(shù)據(jù)直接執(zhí)行,那么只要改掉同名的函數(shù),那么想怎么操作數(shù)據(jù)都可以了。還可以修改參數(shù)值,對(duì)傳到服務(wù)器的數(shù)據(jù)進(jìn)行修改,從而攻擊服務(wù)器。
注意:此方法只能發(fā)起GET請(qǐng)求,通過(guò)jsonp發(fā)送的請(qǐng)求,會(huì)隨帶 cookie 一起發(fā)送。
六、CORS跨域(跨域資源共享)CORS(Cross-Origin Resource Sharing,跨源資源共享)定義了在必須訪問(wèn)跨源資源時(shí),瀏覽器與服務(wù)器應(yīng)該如何溝通。CORS 背后的基本思想,就是使用自定義的 HTTP 頭部讓瀏覽器與服務(wù)器進(jìn)行溝通,從而決定請(qǐng)求或響應(yīng)是應(yīng)該成功,還是應(yīng)該失敗。
注意:此方法IE8以下完全不支持,IE8-10部分支持。
這需要服務(wù)器 和前端配合, 或者 后端 和 前端配合。
可以看看阮老師的:跨域資源共享 CORS 詳解
這里以 php 為例,只需在需要被請(qǐng)求的 php 文件里加上一個(gè)響應(yīng)頭部 header("Access-Control-Allow-Origin:http://127.0.0.1"),后面的域名就是允許請(qǐng)求的域名。這里就是表示允許來(lái)自http://127.0.0.1所有的請(qǐng)求。
127.0.0.1:8080 index.php:
然后就是前端了。IE10及以上、Firefox 3.5+、Safari 4+、Chrome、iOS版 Safari和 Android平臺(tái)中的 WebKit都通過(guò) XMLHttpRequest 對(duì)象實(shí)現(xiàn)了對(duì) CORS 的原生支持。
127.0.0.1:80 index.html:
Document 另一個(gè)頁(yè)面
而IE8 - IE9是通過(guò)XDR對(duì)象實(shí)現(xiàn) CORS 的。
基于XDR的 index.html 代碼如下:
XDR對(duì)象實(shí)現(xiàn)CORS XDR對(duì)象實(shí)現(xiàn)CORS
注意:CORS可以發(fā)起 GET、POST請(qǐng)求,但是發(fā)送的請(qǐng)求,默認(rèn)不會(huì)隨帶 cookie 一起發(fā)送, 也不會(huì)接受后端發(fā)過(guò)來(lái)的 cookie;
要想隨帶cookie 一起發(fā)送。
需要在127.0.0.1:8080 index.php添加 header("Access-Control-Allow-Credentials:true");頭部,然后在127.0.0.1:80 index.html中var xhr = new XMLHttpRequest();后面添加xhr.withCredentials = true;
同源策略認(rèn)為域和子域?qū)儆诓煌挠?,如?br>child1.a.com 與 a.com,
child1.a.com 與 child2.a.com,
xxx.child1.a.com 與 child1.a.com
兩兩不同源,可以通過(guò)設(shè)置 document.domain="a.com",瀏覽器就會(huì)認(rèn)為它們都是同一個(gè)源。想要實(shí)現(xiàn)以上任意兩個(gè)頁(yè)面之間的通信,兩個(gè)頁(yè)面必須都設(shè)置documen.damain="a.com"。
此方式的特點(diǎn):
只能在父域名與子域名之間使用,且將 xxx.child1.a.com域名設(shè)置為a.com后,不能再設(shè)置成child1.a.com。
存在安全性問(wèn)題,當(dāng)一個(gè)站點(diǎn)被攻擊后,另一個(gè)站點(diǎn)會(huì)引起安全漏洞。
這種方法只適用于 Cookie 和 iframe 窗口。
下面來(lái)模擬一下,在a.com 與 child1.a.com 之間通信。如果要在本機(jī)測(cè)試,請(qǐng)自行更改host 等,訪問(wèn)的都是本機(jī)80端口,這里就不在累述了。
a.com index.html
Document 主頁(yè)面
child1.a.com index.php
child1.a.com index1.html
Document child
注意:此方法可以發(fā)起 GET、POST 請(qǐng)求,發(fā)起的請(qǐng)求不會(huì)隨帶 cookie 一起發(fā)送,也不能接受后端發(fā)過(guò)來(lái)的 cookie
八、HTML5的postMessage方法這是html5 新加的方法。
這個(gè)方法允許一個(gè)頁(yè)面的腳本發(fā)送數(shù)據(jù)到另一個(gè)頁(yè)面的腳本中,不管腳本是否跨域。在一個(gè)window對(duì)象上調(diào)用postMessage()會(huì)異步的觸發(fā)window上的onmessage事件,然后觸發(fā)定義好的事件處理方法。一個(gè)頁(yè)面上的腳本仍然不能直接訪問(wèn)另外一個(gè)頁(yè)面上的方法或者變量,但是他們可以安全的通過(guò)消息傳遞技術(shù)交流。
比如說(shuō)父頁(yè)面為127.0.0.1:80 的頁(yè)面,傳送數(shù)據(jù)給 127.0.0.1:8080 的子頁(yè)面:
127.0.0.1:80 index.html
Document 父頁(yè)面
127.0.0.1:8080 index.html
Document 子頁(yè)面
然后訪問(wèn):127.0.0.1:80/index.html,就得到想要的結(jié)果了,這方法通常用來(lái)進(jìn)行兩個(gè)窗口通信。
九、HTML5的WebSocket現(xiàn)代瀏覽器允許腳本直連一個(gè)WebSocket地址而不管同源策略。然而,使用WebSocket URI的時(shí)候,在請(qǐng)求中插入Origin頭就可以標(biāo)識(shí)腳本請(qǐng)求的源。為了確保跨站安全,WebSocket服務(wù)器必須根據(jù)允許接受請(qǐng)求的白名單中的源列表比較頭數(shù)據(jù)。
這個(gè)因?yàn)樾枰蠖说闹С?,而且比較復(fù)雜,這里就不舉例子了,感興趣的可以去查閱資料。
這里貼一個(gè)阮老師的websocket教程吧:WebSocket 教程
十、window.namewindow對(duì)象有一個(gè)name屬性,該屬性有一個(gè)特征:即在一個(gè)窗口的生命周期內(nèi),窗口載入的所有的頁(yè)面都是共享一個(gè)window.name的,每一個(gè)頁(yè)面對(duì)window.name都有讀寫的權(quán)限,window.name是持久的存在于一個(gè)窗口載入的所有頁(yè)面中的,并不會(huì)因?yàn)樾碌捻?yè)面的載入而被重置。
因此,就可以利用此特性,進(jìn)行跨域通信。
127.0.0.1:80 index.html
Document window.name
127.0.0.1:8080 index.html
Document
這時(shí),訪問(wèn)127.0.0.1:80/index.html,跳轉(zhuǎn)到的127.0.0.1:8080/index.html就能接受傳過(guò)來(lái)的數(shù)據(jù)了。
十一、location.hash原理是利用location.hash來(lái)進(jìn)行傳值。在url: http://a.com#helloword中的‘#helloworld’就是location.hash。
127.0.0.1:80 index.html
Document window.name
127.0.0.1:8080 index.html
Document
這時(shí),訪問(wèn)127.0.0.1:80/index.html,跳轉(zhuǎn)到的127.0.0.1:8080/index.html就能接受傳過(guò)來(lái)的數(shù)據(jù)了。
十二、proxy 跨域這個(gè)完全是后端的實(shí)現(xiàn),我就不說(shuō)了,我也搞不懂,也沒(méi)意義。哈哈。
這里說(shuō)的還是皮毛,這些跨域方案只是工具,怎么利用,就看你了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97993.html
摘要:同源策略及跨域訪問(wèn)同源策略同源策略約束了兩個(gè)域之間資源的加載方式,是一個(gè)很重要的安全機(jī)制用來(lái)隔離那些有潛在安全隱患的文檔。 同源策略及跨域訪問(wèn) 同源策略 同源策略(Same-origin policy)約束了兩個(gè)域之間資源的加載方式,是一個(gè)很重要的安全機(jī)制用來(lái)隔離那些有潛在安全隱患的文檔。 何為源(orgin) 一個(gè)源由一個(gè)URL的協(xié)議(protocol)、主機(jī)(host)和端口(po...
摘要:扯了這么多,自然不是為了吹水,而是要為了引出前端開發(fā)的一個(gè)重要的知識(shí)點(diǎn)同源策略什么是同源策略出于保護(hù)用戶信息安全的目的,現(xiàn)在的瀏覽器都會(huì)實(shí)施同源策略這個(gè)政策,所謂同源策略指的是不同源的客戶端腳本在沒(méi)有明確授權(quán)情況下,不允許讀寫對(duì)方的資源。 導(dǎo)語(yǔ)你家的小孩帶了他的朋友來(lái)你們的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿東西吃你自然是不會(huì)阻止,但是如果你家小孩的朋友人品不行,亂拿東西吃、...
摘要:扯了這么多,自然不是為了吹水,而是要為了引出前端開發(fā)的一個(gè)重要的知識(shí)點(diǎn)同源策略什么是同源策略出于保護(hù)用戶信息安全的目的,現(xiàn)在的瀏覽器都會(huì)實(shí)施同源策略這個(gè)政策,所謂同源策略指的是不同源的客戶端腳本在沒(méi)有明確授權(quán)情況下,不允許讀寫對(duì)方的資源。 導(dǎo)語(yǔ)你家的小孩帶了他的朋友來(lái)你們的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿東西吃你自然是不會(huì)阻止,但是如果你家小孩的朋友人品不行,亂拿東西吃、...
摘要:上節(jié)我們講了同源策略,這節(jié)我們講講如何跨域。當(dāng)這些從的腳本執(zhí)行出錯(cuò),因?yàn)檫`背了同源策略為了保證用戶信息不被泄露,錯(cuò)誤信息不會(huì)顯示出來(lái),取而代之只會(huì)返回一個(gè)。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識(shí)的中心思想,我們開課啦(每...
摘要:同源策略是什么同源策略是瀏覽器的一個(gè)安全功能,不同源的數(shù)據(jù)禁止訪問(wèn)。或許你可以說(shuō)驗(yàn)證,在瀏覽器沒(méi)有同源策略的情況下這些都可以繞過(guò)去??偨Y(jié)同源策略是蠻好的,防御了大部分的攻擊。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識(shí)的中心思...
閱讀 2438·2021-11-11 16:54
閱讀 2675·2021-09-26 09:47
閱讀 4014·2021-09-08 09:36
閱讀 2761·2021-07-25 21:37
閱讀 948·2019-08-30 15:54
閱讀 2563·2019-08-30 14:22
閱讀 3274·2019-08-30 13:57
閱讀 2681·2019-08-29 17:17