Java - 探究前后分离带来的跨域问题
文章目錄
- 為什么會(huì)產(chǎn)生跨域問題
- 同源策略 (Same-origin policy)
- 解決方案
- 服務(wù)端解決方案
- 簡單請(qǐng)求
- 復(fù)雜請(qǐng)求
- 測試
- 簡單請(qǐng)求測試
- 復(fù)雜請(qǐng)求測試
- 代理服務(wù)器,反向代理接口請(qǐng)求
- jsonp 方式
為什么會(huì)產(chǎn)生跨域問題
1995年,Netscape 公司出于安全的考慮在瀏覽器中引入了“同源策略”。
跨域問題只出現(xiàn)在瀏覽器訪問的頁面,因?yàn)檫@是瀏覽器為了保戶用戶安全而制造的策略。假如沒有這層保護(hù),網(wǎng)站就很容易受到跨站偽造請(qǐng)求(CSRF)的攻擊。
同源策略 (Same-origin policy)
瀏覽器端對(duì)請(qǐng)求的處理中,如果兩個(gè) URL 的協(xié)議、域名和端口都相同,我們就稱這兩個(gè)URL 同源
我們來舉幾個(gè)例子
同源
http://www.xxxx.com/indexhttp://www.xxxx.com/module/path1非同源
http://www.xxxx.com/indexhttps://www.xxxx.com/module/path1 http://www.xxxx.com/indexhttp://www.yyyy.com/module/path1 http://www.xxxx.com/indexhttp://www.xxxx.com:8081/module/path1兩個(gè)相同的源之間瀏覽器默認(rèn)其是可以相互訪問資源和操作 DOM 的。兩個(gè)不同的源之間若想要相互訪問資源或者操作 DOM,那么會(huì)有一套基礎(chǔ)的安全策略的制約。
- 安全性: 瀏覽器要防止當(dāng)前站點(diǎn)的私密數(shù)據(jù)不會(huì)向其他站點(diǎn)發(fā)送
如當(dāng)前站點(diǎn)的Cookie,LocalStorage,IndexDb 不會(huì)被發(fā)送到其他站點(diǎn)或被其他站點(diǎn)腳本讀取到。
無法跨域獲取Dom,無法發(fā)送Ajax請(qǐng)求。
- 可用性:大型站點(diǎn)的圖片,音視頻等資源,希望部署在獨(dú)立服務(wù)器上,為緩解當(dāng)前服務(wù)的壓力,開放某些特定的方式,訪問非同源站點(diǎn)
如:<script><img><iframe><link><vedio>等,可以同src屬性跨域訪問 允許跨域提交表單/或重定向請(qǐng)求
解決方案
服務(wù)端解決方案
跨域請(qǐng)求分兩種情況
簡單請(qǐng)求
請(qǐng)求從domain a 發(fā)過來, 請(qǐng)求到web domain b , 如果這個(gè)時(shí)候domain b 返回一個(gè)允許,可以解決這個(gè)問題。
服務(wù)端解決方案: 在http響應(yīng)頭中添加 Access-Control-Allow-Origin 頭,值為信任的站點(diǎn)
復(fù)雜請(qǐng)求
不符合簡單請(qǐng)求條件的即為復(fù)雜請(qǐng)求,訪問跨域資源前,需要發(fā)起preflight預(yù)檢請(qǐng)求(OPTIONS請(qǐng)求)詢問何種請(qǐng)求是被允許的,預(yù)檢請(qǐng)求失敗,則不會(huì)發(fā)起正式的業(yè)務(wù)請(qǐng)求,預(yù)檢請(qǐng)求成功,然后發(fā)起正式請(qǐng)求。
測試
隨便寫個(gè)spring boot 的工程,啟動(dòng)2個(gè)端口 一個(gè)8080 一個(gè)8081 ,訪問8080的頁面,調(diào)用8081的后臺(tái)服務(wù) , 用來測試
簡單請(qǐng)求測試
來看第一個(gè)
CASE1: 【GET請(qǐng)求】
點(diǎn)擊訪問
服務(wù)端后臺(tái)的代碼
添加
response.addHeader("Access-Control-Allow_origin","http://localhost:8080");重啟后, 重新測試
CASE2: 【表單請(qǐng)求】
目前的后端代碼
來 測試走一波
重啟重新測試 , OK
復(fù)雜請(qǐng)求測試
【復(fù)雜請(qǐng)求】
和上面Case2的請(qǐng)求一模一樣,除了 Content-Type , 那 還能用上面的添加響應(yīng)頭解決嗎?
答案是不能的。。。。。
我們用wireshark來跟蹤下 option 預(yù)檢的 請(qǐng)求
Spring Boot 官方給出了解決方案
我們就看全局的這個(gè)配置吧
請(qǐng)求下 跟蹤下
good
代理服務(wù)器,反向代理接口請(qǐng)求
location /api {rewrite ^/api/(.*)$ /$1 break;proxy_pass http://localhost:8081/;}說一下為什要rewrite, 因?yàn)?api 這個(gè)前綴僅僅用于前臺(tái)頁面發(fā)請(qǐng)求時(shí)候攜帶, 后臺(tái)并沒有 api這個(gè)context, 所以需要在nnginx 通過rewrite機(jī)制來將api 替換掉 。
rewrite ^/api/(.*)$ /$1 break;這個(gè)就是 一 /api開頭的請(qǐng)求, 替換為 $1 , 這個(gè)$1就是 請(qǐng)求中/api后面的內(nèi)容, break 即為 匹配到則不往后面找了。
jsonp 方式
基于
可用性:大型站點(diǎn)的圖片,音視頻等資源,希望部署在獨(dú)立服務(wù)器上,為緩解當(dāng)前服務(wù)的壓力,開放某些特定的方式,訪問非同源站點(diǎn) 。
如:<script><img><iframe><link><vedio>等,可以同src屬性跨域訪問 允許跨域提交表單/或重定向請(qǐng)求
后臺(tái)代碼
測試走一波
了解下就行了,實(shí)際中很少會(huì)用到j(luò)sonp來解決跨域問題
總結(jié)
以上是生活随笔為你收集整理的Java - 探究前后分离带来的跨域问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解分布式技术 - Service
- 下一篇: Spring Session - Co