當前位置:編程學習大全網 - 源碼下載 - 使用nginx代理解決跨域問題

使用nginx代理解決跨域問題

先說說跨域這事情吧。早在13年,我剛接觸前端開發的時候就遇到了跨域,那時候剛開始流行前後端分離。解決跨域就是直接用get jsonp。還是小白的我,也沒有去想跨域的其它解決方式和為什麽要采用這種解決方式。

? 最近,做壹個二次開發的項目,也碰到了用網頁請求http post,瀏覽器跨域,不能獲取返回數據的問題,所以再次來梳理下這個跨域,為什麽最後選擇了nginx代理。

? 首先,什麽是跨域呢?首先需要了解的是同源和跨源的概念。對於相同源,其定義為:如果協議、端口(如果指定了壹個)和主機對於兩個頁面是相同的,則兩個頁面具有相同的源。 只要三者之壹任意壹點有不同,那麽就為不同源。 同源策略限制從壹個源加載的文檔或腳本如何與來自另壹個源的資源進行交互。這是壹個用於隔離潛在惡意文件的關鍵的安全機制。當壹個資源從與該資源本身所在的服務器的域或端口不同的域或不同的端口請求壹個資源時,資源會發起壹個跨域 HTTP 請求。跨域不壹定是瀏覽器限制了發起跨站請求,而也可能是跨站請求可以正常發起,但是返回結果被瀏覽器攔截了。 簡單的來說,出於安全方面的考慮,頁面中的JavaScript無法訪問其他服務器上的數據,即“同源策略”。而跨域就是通過某些手段來繞過同源策略限制,實現不同服務器之間通信的效果。

? 跨域的解決方案也有很多種。

? 類型壹:有些瀏覽器可以設置 ,降低它的安全性。但是對於壹個網站,要求設置瀏覽器是不切合實際的。

? 類型二:直接用form方式 ,這種情況下不是ajax請求,而是直接訪問目標地址了,不存在跨域問題,但是這個頁面已經跳轉了。而我們想實現的只是取另外壹個地址的數據到本地顯示而已。

? 類型三:服務端語言是能夠處理的情況下。

1、CORS 是壹個W3C標準,全稱是”跨域資源***享”(Cross-origin resource sharing)。它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。跨域資源***享( CORS )機制允許 Web 應用服務器進行跨域訪問控制,從而使跨域數據傳輸得以安全進行。其需要服務端和客戶端同時支持。

? 對於簡單請求,瀏覽器直接發出CORS請求。具體來說,就是在頭信息之中,增加壹個Origin字段。如果Origin指定的源,不在許可範圍內,服務器會返回壹個正常的HTTP回應。瀏覽器發現,這個回應的頭信息沒有包含Access-Control-Allow-Origin字段(詳見下文),就知道出錯了,從而拋出壹個錯誤,被XMLHttpRequest的onerror回調函數捕獲。註意,這種錯誤無法通過狀態碼識別,因為HTTP回應的狀態碼有可能是200。如果Origin指定的域名在許可範圍內,服務器返回的響應,會多出幾個頭信息字段。 Access-Control-Allow-Origin 該字段是必須的。它的值要麽是請求時Origin字段的值,要麽是壹個*,表示接受任意域名的請求。 Access-Control-Allow-Credentials 該字段可選。 Access-Control-Expose-Headers 該字段可選。

? 可以說這種辦法主要在header上下功夫,設置Access-Control-Allow-Origin為所有*允許訪問。雖然說它支持所有的請求方式,post,delete,put等等,但是它不能兼容ie6,7等等。

? 例如下圖的nodejs? express 例子:

? 2、服務端的http ajax請求全部改為 get jsonp方式 。該方式能夠兼容老式瀏覽器。

3、iframe window.name 這種傳值得方式很巧妙,兼容性也很好。但是在要訪問數據的地址那個服務器要有壹個空的中間頁面拿來用。

4、postMessage , html5 window.postMessage。 同iframe window.name有點像,也是需要服務端有個空的html拿來接收數據。而且現在的postMessage兼容性也不好。

? 5、document.domain 修改為頂級域名。

? 6、 WebSocket ,協議不實行同源政策,只要服務器支持,就可以通過它進行跨源通信。

類型四:不是簡單的前後端。假如有個第三方的api,自己有壹個網站前端,壹個網站後端。

? 1、自己的網站端和後端源碼放在同壹個服務端口和目錄下,不存在跨域。當直接用網站前端的http訪問第三方api,瀏覽器跨域。此時,改為由網站後端的服務端語言訪問,做個中間人,將訪問的數據給網頁前端。

? 2、網站前端和後端不是同源的,采用以上的跨域方案,譬如CORS。同樣的網站後端做中間人,訪問第三方api,再轉給網頁前端。

? 3、使用nginx 反向代理解決跨域問題。 網站前端訪問nginx服務的地址,nginx設置代理地址為訪問第三方api地址,當訪問代理地址的時候,瀏覽器訪問的是nginx服務的地址,實際是訪問第三方api地址。

註意:此時,如果目錄下有個proxy.html,因為設置代理地址是/proxy,碰到這個地址就被轉到”https://192.168.18.175:8088/api/v1.0.2/“,所以要訪問proxy.html是訪問不到的。

? 4、使用nginx代理地址是解決生產環境發布的問題了,那麽我在開發的時候使用angular這樣需要打包的框架怎麽辦呢。當然在開發環境下,angular也是由類似代理地址的解決方案的。

(1)創建配置代理文件:假設後端服務的訪問地址為http://192.168.19.175:8088/api/v1.0.2/login,我們可以創建壹個proxy.conf.json文件,放在package.json同目錄下。

(2)改寫package.json文件 ,采用--proxy-config命令(angular自帶的命令)。

(3)ajax訪問代理地址

此時, 執行 npm start ,即可發現,瀏覽器訪問http://localhost:4200/api/v1.0.2/login 的同源地址,實際上是訪問http://192.168.18.175:8088/api/v1.0.2/login.

? angular在開發環境下代理地址的方法類似在生產環境下使用的nginx代理。但是測試angular是有壹個/api代理地址的巧合。剛好第三方api上面的地址有個api,才能使用這個地址,並且能夠簡寫壹個api,才能成功訪問,如果更改為其它的,譬如proxy,就測試失敗。而且proxy.conf.json文件下的設置也只能是域名和端口。所以,本人測試,這或許是個巧合或者是缺陷。

五、其它

? 當然,跨域這個算是歷史性的問題,以後也會存在這個問題。除了上面各種方法,以及根據各種方法使用的場合,還有許多其它的方法。例如各大流行框架react,vie應該也有像angular壹樣,能夠處理跨域的開發環境方案,接下來,還是要繼續學習和積累。

  • 上一篇:蕪湖招標介紹?
  • 下一篇:微信上的H5是什麽意思?
  • copyright 2024編程學習大全網