Nginx 通過反向代理解決跨域問題


一、問題的由來

隨着項目不斷地演進,難免會涉及到微服務架構。當采用微服務架構之后,web項目自然免不了面臨跨域的問題。最近學習了一下這方面的知識,做個小筆記方便以后回顧,希望各位大神多多指教。

二、跨域究竟是個什么東東

跨域問題的出現是由於瀏覽器出於安全而遵守一個叫做“同源策略”的約定,而限制訪問不同源下的資源而導致的。具體哪些情況屬於同源,可參考大神文章--“什么是同源策略”。

既然是瀏覽器都遵循的一個公共策略,而且是出於安全性考慮的,那么我們遇到跨域問題就要謹慎解決,不然則會導致應用安全性下降。著名的CSRF(Cross Site Request Forgery),即跨站請求偽造,

如果沒有同源策略的限制的話就能輕易實現。雖然由於同源策略的限制,web應用的安全性提高了但同時也帶來一些麻煩,比如我們服務器有兩個端口,這時我們想在Ajax調用另一個端口的服務就不行了。

就好比中國對一些外網的IP封鎖,它保護了國家重要關鍵信息的安全,同時也給大家查資料帶來了一些麻煩。可參考大神文章--“一個解除跨域限制的瀏覽器有多危險”。

 

值得強調的是,跨域問題是瀏覽器對於訪問的限制,可以通過禁用瀏覽器同源測略來解除限制。可參考大神文章--“禁用瀏覽器同源策略的方法”。

對於跨域請求,如果服務不可用的情況下,那么控制台的錯誤是這樣的:

顯示連接被拒絕了,而當服務可用的時候,控制台返回的錯誤是這樣的:

可以發現如果沒有做相應的跨域處理的話,瀏覽器其實是能發送這個請求的,但是當瀏覽器檢測這是一個不被允許的跨域請求的話,則會放棄這個請求,返回失敗。

在網上看到一個圖很形象地描述了這一過程:

這也就說明了,跨域請求是由瀏覽器來攔截控制的,也就解釋了簡單粗暴地直接關閉瀏覽器的同源策略檢查就能實現跨域訪問的原理,但是這樣就等於完全放棄了安全檢查,那么該怎么辦呢?

著名文學家魯迅先生曾經說過----“只要思想不滑坡,方法總比困難多”。IP封鎖阻擋不了大家查資料的熱情,各種FQ軟件層出不窮,當然跨域問題也是有相應的解決方案的。

三、解決跨域問題的正確姿勢

解決跨域問題有很多方法,像什么jasonp、document.domain + iframe跨域、location.hash + iframe跨域、跨域資源共享(CORS)等等。每種方法都有自己的優缺點,大家可根據需求自行選擇相應的解決方案,

具體可參看大神文章--“前端解決跨域的九種方法”。

我這里采用的是“nginx反向代理跨域”,即通過配置nginx代理來實現請求的轉發從而實現跨域訪問。相信大家都聽過nginx的大名,它可以用來做靜態http服務器、正反向代理、負載均衡、虛擬主機等。

使用nginx來解決跨域問題其實就是利用了其反向代理的功能。如果不清楚nginx正反向代理的同學,可參考大神文章--“Nginx的正向代理和反向代理”。

四、進入正題

當然在這之前需要大家先了解nginx的相關知識,大家可自行百度,nginx也是個好東西可以了解了解。

先用HBuilder創建一個簡單的頁面,兩個按鈕分別發送請求到Java服務器(5001端口)和.NET Core服務器(5000端口),HBuilder頁面所在端口為8848。

然后創建兩個api接口,一個Java的,一個.NET Core的,與之前說的端口對應上,然后開啟服務,接口測試正常。沒有配置nginx時訪問不出意料地顯示跨域錯誤:

接下來就是配置nginx了,安裝nginx后找到配置文件nginx.conf,修改轉發規則:

nginx的核心在於配置文件的編寫,這里我簡單地寫了三條轉發規則,nginx還支持更復雜的轉發配置,更詳細的nginx配置規則大家可自行百度學習。然后測試頁面的Ajax地址做簡單修改,使之與nginx的轉發規則匹配:

接下來就是見證奇跡的時刻了:

訪問成功了,並且可以發現返回請求的服務器類型是nginx,通過nginx將配置了轉發規則的請求轉發到指定服務器,而沒有配置的地址還是會被瀏覽器攔截的,實現了安全可控的跨域訪問。

好了,到這里算是完美解決了跨域問題,當然實際開發過程中還可能出現各種各樣的問題,還是需要不斷學習。加油,奧力給!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM