1. 程式人生 > >Geoserver通過ajax跨域訪問服務資料的方法(含使用者名稱密碼認證的配置方式)

Geoserver通過ajax跨域訪問服務資料的方法(含使用者名稱密碼認證的配置方式)

Goeserver資料有兩種,一種需進行使用者密碼的許可權認證,一種無須使用者密碼。對於網上跨域訪問Geoserver資料的種種方法,對這2種資料並非通用。

筆者將Geoserver官方下載的Geoserver.war包部署到linux伺服器,通過前端 ajax 訪問geoserver資料失敗,其中包含跨域問題和使用者名稱密碼認證問題,查詢網上各類方法進行嘗試,結果瀏覽器控制檯分別報出了401,403和跨域錯誤提示。其中:

401錯誤:ajax未進行使用者名稱密碼驗證導致;

403錯誤:使用者名稱密碼驗證失敗導致;

跨域錯誤(兩種可能):

  1,真實的跨域導致;

  2,403錯誤引發,此時也可能真的存在跨域但不一定。

解決方法:

1. jetty方式(對於跨域,親測可用,但使用者名稱密碼認證可否配置未探索)

步驟1, web.xml配置跨域:

在Geoserver的釋出包中找到WEB-INF/web.xml,開啟新增如下配置:

<filter>
        <filter-name>cross-origin</filter-name>
        <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
        <init-param>
        <param-name>allowedOrigins</param-name>
        <param-value>*</param-value>
        </init-param>
        <init-param>
        <param-name>allowedMethods</param-name>
        <param-value>GET,POST,OPTIONS</param-value>
        </init-param>
        <init-param>
        <param-name>allowedHeaders</param-name>
        <param-value>x-requested-with,content-type,access-control-allow-origin,access-control-allow-methods,authorization,accept</param-value>
        </init-param>
</filter>
<filter-mapping>
        <filter-name>cross-origin</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>

步驟2,新增與Geoserver版本對應的jetty jar包。

下載jetty.sevlets.jar,jetty.utli.jar,jetty.sevlet.jar三個(前兩個必須,第三是否必須未驗證),複製到Geoserver釋出包的/WEB-INF/lib資料夾下。

注意:jetty 的jar包要與Geoserver相容,筆者用的是 geoserver-2.13.2-war 和 jetty的 9.2.13.v20150730版本。若想確定版本的對應關係,我瞭解到的一種傻瓜方法是,下載對應的Geoserver 的windows安裝版,安裝後在安裝包中可找到相應版本的這三個jar 包,可直接複製使用。

步驟3. ajax程式碼

       var url="http://10.0.30.63:8093/geoserver/tiger/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=tiger:poi&maxFeatures=50&outputFormat=application%2Fjson";
            $.ajax({
                type: "get",
                url: url,
                success: function(response){
                    console.log(response);
                },
                error:function(XMLHttpRequest, textStatus, errorThrown) {
                    alert(XMLHttpRequest.status);
                    alert(XMLHttpRequest.readyState);
                    alert(textStatus+";"+errorThrown);
                },
            })

2. Tomcat配置方式(可同時解決跨域和使用者密碼驗證的問題,親測可用)

 步驟1. web.xml配置

在Geoserver釋出包的 /WEB-INF/web.xml檔案中新增如下配置:

可參考官網:http://tomcat.apache.org/tomcat-9.0-doc/config/filter.html#CORS_Filter

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>

  <!--關鍵部位1,cors.allowed.origins的值
    1.若需進行使用者密碼驗證,則其值不可為“*”,可為需進行跨域的應用域名埠的連結(如下所示),因為為“*”的該項與下面的cors.support.credentials不可同時存在,否則tomcat啟動會出錯。
    2.若無序進行使用者名稱密碼驗證,則其值可為“*”。若為“*”,則下面的cors.support.credentials項要刪除。
 -->
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>http://10.70.1.183:8080,http://localhost:8080</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>

<!--關鍵部位2,cors.support.credentials項
  1,若需進行使用者名稱密碼驗證,則必須存在;
  2. 若無效進行使用者名稱密碼驗證,僅設定跨域,則可刪除
-->

  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

步驟2. ajax程式碼

            url='http://10.0.30.63:8093/geoserver/rest/fonts.json';

            $.ajax({
                type: "get",
                url: url,
                headers: {
                    Authorization:"Basic YWRtaW46Z2Vvc2VydmVy",
                },
//對於使用者名稱密碼驗證,headers中Authorization項必須有,其值為加密後的“使用者名稱:密碼”,可以換成下面beforeSend的寫法(兩種不同的設定http請求頭的方式)
//                 beforeSend:function(xhr){
//                     xhr.setRequestHeader ("Authorization","Basic YWRtaW46Z2Vvc2VydmVy");
//                 },

                dataType: "json",
                success: function(response){
                    console.log(response);
                },
                error:function(XMLHttpRequest, textStatus, errorThrown) {
                    alert(XMLHttpRequest.status);
                    alert(XMLHttpRequest.readyState);
                    alert(textStatus+";"+errorThrown);
                },
            })