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