解決Geoserver請求跨域的幾種思路


文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/

1.背景描述

     跨域問題是瀏覽器同源安全制引起的特別常見的問題。不同前端語言針對跨域解決方法有所區別。比如Flex語言做跨域請求時,如果中間件存有跨域文件(crossdomain.xml)則可以輕松實現跨域。

    而JS開發的前端,針對GET請求則又可以通過JSONP方式解決。補充一下JSONP的原理:通過創建一個 script 標簽,將 src 設置為目標請求,插入到 DOM中,服務器接受該請求並返回數據,數據通常被包裹在回調鈎子中。根據JSONP的實現原理,我們可以看到其無法支持POST請求方式。

    回到我們文章的主題,使用tomcat發布了Geoserver,前端JS腳本通過常規JSONP的請求方式失效,此時如何實現跨域請求呢?

    這里我總結兩種思路,一種是轉發代理方案,另一種是中間件支持跨域共享機制(CORS)。

2.方案一:轉發代理

2.1基於Nginx的代理

    假設有A服務器和B服務器,用戶前端加載了A服務器的JS資源,然后該JS向B服務器后台發送請求,此時發生了跨域。基於Nginx的解決方案則是,在C(或者A或者B或者其他)服務器上搭建一個Nginx服務器,該服務器對A服務和B服務均做統一端口的代理,即前端通過同一IP:Port訪問A上和B上的資源,從而避免瀏覽器的跨域問題。

    方案示意圖為:

 

2.2自定義實現代理轉發(基於A服務器)

2.2.1原理

    目前A服務器上的腳本想訪問B服務器上的服務會引發跨域,如果我們將A服務器的腳本訪問轉移到A服務器上的后台對B服務器后台的訪問,則可以規避跨域問題。

    方案示意圖為:

 

2.2.2具體實現

    如果我們的代碼層面僅僅是單獨針對某個請求讓其轉移至后台,則其他類似問題則無法通用此解決方案。這里我們可以設計一種通用型的解決方案:

    a.將所有需要走后台避免跨域的請求統一定義為http://IP:Port/name/proxy?Url=BServerUrl

    b.后台對應的proxy方法中獲取到Url后的參數,並且再次對Url后的參數進行傳遞參數的解析(BServerUrl中可以用&包含正常參數)。

    c.轉發解析到的B請求,獲取返回結果再返回至前端。

    注意,在實現中,我們還要同時考慮代理轉發的Get請求和Post請求方式:

 

3.方案二:中間件跨域共享機制(CORS)

3.1CORS原理簡介

    出於安全原因,瀏覽器限制從腳本內發起的跨源HTTP請求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 這意味着使用這些API的Web應用程序只能從加載應用程序的同一個域請求HTTP資源,除非使用CORS頭文件。

    CORS的原理為:跨域資源共享標准新增了一組 HTTP 首部字段,允許服務器聲明哪些源站有權限訪問哪些資源。另外,規范要求,對那些可能對服務器數據產生副作用的 HTTP 請求方法(特別是 GET 以外的 HTTP 請求,或者搭配某些 MIME 類型的 POST 請求),瀏覽器必須首先使用 OPTIONS 方法發起一個預檢請求(preflight request),從而獲知服務端是否允許該跨域請求。服務器確認允許之后,才發起實際的 HTTP 請求。在預檢請求的返回中,服務器端也可以通知客戶端,是否需要攜帶身份憑證(包括 Cookies 和 HTTP 認證相關數據)。

    以上內容均摘抄於:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

3.2具體實現

    先下載CORS對應的Jar:

    <!-- cors-filter-->
    <dependency org="com.thetransactioncompany" name="java-property-utils" rev="1.10" conf="common-release->default;" />
    <dependency org="com.thetransactioncompany" name="cors-filter" rev="2.5" conf="common-release->default;"/>

    在Geoserver的Web.xml中加上如下配置:

 

    重啟Geoserver后測試。

    測試環境說明:在同一台機器上測試,系統采用8081端口,Geoserver服務采用8080端口,不同端口同樣會導致跨域。測試結果為跨域成功。

 


免責聲明!

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



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