跨域与跨站
同源策略
瀏覽器有同源策略,如果兩個URL的協議,域名,端口完全一致才是同源
有一個不一致就是跨域
示例
以該頁面為例:https://sugarat.top/bigWeb/browser/cros.html
- 協議:https
- 域名:sugarat.top
- 端口:443 (https默認443,http默認80)
| URL | 是否同源 | 理由 |
| https://sugarat.top | ? | 協議,域名,端口 均一致 |
| http://sugarat.top:8080 | ? | 協議,端口不一致 |
| https://sugarat.top:8080 | ? | 端口 不一致 |
| https://ep.sugarat.top | ? | 域名 不一致 |
| https://imgbed.sugarat.top | ? | 域名 不一致 |
同源策略限制
?1.DOM: 禁止操作非源頁面的DOM與JS對象
? ? ?這里主要場景是iframe跨域的情況,非同源的iframe是限制互相訪問的
?2.XmlHttpRequest: 禁止使用XHR對象向不同源的服務器地址發起HTTP請求,即不能發送跨域ajax請求這里主要場景是iframe跨域的情況,非同源的iframe是限制互相訪問的? ?
? ? ?主要用來防止CSRF(跨站請求偽造)攻擊
?3.本地存儲: Cookie、LocalStorage 和 IndexDB 無法跨域讀取
非同源也有可以通信的方案,后文會做出介紹
為什么需要同源策略🤔
這里先列舉反例
例1:如果iframe可以跨域,就會有以下攻擊場景
這樣一次攻擊就完成了
例2:如果ajax可以跨域,就會有以下攻擊場景
這樣一次攻擊就完成了
采用同源策略限制跨域訪問,主要就是為了用戶信息的安全考慮
跨域
違反同源策略就是跨域
影響
最常見的兩種跨域場景就是
- ajax跨域
- iframe跨域
跨域示例
ajax跨域
執行下面代碼會在開發者工具中的 Console面板看到以下錯誤信息
Access to fetch at 'https://ep.sugarat.top/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.?
<body><button id="btn">click me</button><script>const $btn = document.getElementById('btn')$btn.onclick = function () {fetch('https://ep.sugarat.top/', {method: 'get'})}</script> </body>iframe跨域
無法跨域訪問iframe中的DOM元素信息
<body><iframe src="https://sugarat.top/" width="100%" height="1000px" frameborder="0"></iframe><script>const iframe = document.getElementsByTagName('iframe')[0]console.log(iframe.contentWindow.document.children[0].outerHTML)// <html><head></head><body></body></html></script> </body>跨站
Cookie與此息息相關,Cookie實際上遵守的是“同站”策略
什么是同站
只要兩個 URL 的 eTLD+1 相同即是同站,不需要考慮協議和端口
eTLD: (effective top-level domain) 有效頂級域名,注冊于 Mozilla 維護的公共后綴列表(Public Suffix List)中,如.com、.co.uk、.github.io,.top 等
eTLD+1: 有效頂級域名+二級域名,如 taobao.com,baidu.com,sugarat.top
tips: 這里的一級,二級域名主要指計算機網絡中規定的,與通常業務開發中所指的一二級域名有些許差異
還以該url為例:https://sugarat.top/bigWeb/browser/cros.html
- eTLD: .top
- eTLD+1: sugarat.top
| URL | 是否同站 | 理由 |
| sugarat.top | ? | eTLD+1一致 |
| ep.sugarat.top | ? | eTLD+1一致 |
| ep.sugarat.top:8080 | ? | eTLD+1一致 |
| baidu.com | ? | eTLD 不一致 |
只要eTLD+1不同就是跨站
對Cookie的影響
因為Cookie遵循的是同站策略,很多網站都是把一些權限,用戶行為,主題,個人的配置信息
所以很多網站會把這些信息存在二級域名下,即讓其子域名能夠共享這些配置,鑒權信息
以taobao舉例
打開 taobao.com,可以看到其cookie有
?
我們在 ai.taobao,com下也可看到這些cookie
?
預檢請求
使用后端開啟CORS解決跨域的方式,瀏覽器會把請求分成兩種類型
- 簡單請求
- 復雜請求
簡單請求
觸發簡單請求的條件
1.請求方法僅限于:
- GET
- HEAD
- POST
2.Content-Type僅限于:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
復雜請求
非簡單請求的即為復雜請求↓
對于復雜請求,首先會發起一個預檢請求,請求方法為options,通過該請求來判斷服務器是否允許跨域
與預檢請求有關的以Access-Control-開頭的響應頭:
- Access-Control-Allow-Methods:表明服務器支持的所有跨域請求的方法
- Access-Control-Allow-Headers:表明服務器支持的頭信息
- Access-Control-Max-Age:指定本次預檢請求的有效期,單位為秒,在此期間,不用再重新發型新的預檢請求
總結
- 上一篇: SVN Cannot verify lo
- 下一篇: 不可不看的Java基础知识整理,注释、关