【问题标题】:How to solve CORS problems between OpenLayers v6.14.1 and GeoServer 2.20.2 in Reactjs?如何解决 Reactjs 中 OpenLayers v6.14.1 和 GeoServer 2.20.2 之间的 CORS 问题?
【发布时间】:2022-10-17 19:33:01
【问题描述】:

我正在尝试通过 reactjs 中 OL v6.14.1 中的“tileLoadFunction”将 WMS 图层作为平铺图层,但是当我在以下代码中运行时,我会收到 CORS 错误消息:

  map.addLayer(
      new TileLayer({
        source:new TileWMS({
          url:`http://194.105.111.10:8080/geoserver/${selectedLayer[i].datastore}/wms`,
          visible:true,
          projection:'EPSG:4326',
          params:{'LAYERS':layerName,'TILED': true},
          serverType:'geoserver',
          tileLoadFunction:function(image, src) {
            var xhr = new XMLHttpRequest();
            xhr.responseType = 'blob';
            xhr.open('GET', src);
           
          xhr.setRequestHeader("Access-Control-Allow-Origin","http://194.105.111.10:3000")
          xhr.setRequestHeader('Authorization', 'Bearer f5711f9d-aa2d-4067-p5a9-af913vd16a21');
          xhr.onload = function() {
                var objectURL = URL.createObjectURL(xhr.response);
                image.getImage().onload = function() {
                    URL.revokeObjectURL(objectURL);
                    
      };
      image.getImage().src = objectURL;
      };
      xhr.send();
      },
                
      }),
      name:`${selectedLayer[i].name}`
    }))

GET http://194.105.111.10:8080/geoserver/higU1EU8kM6eJtKaHg14USMyTsQSOpP6/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=higU1EU8kM6eJtKaHg14USMyTsQSOpP6%3Acontour_line&TILED=true&WIDTH=256&HEIGHT=256&CRS=EPSG%3A4326&STYLES=&BBOX=22.5%2C67.5%2C33.75%2C78.75 net::ERR_FAILED

Access to XMLHttpRequest at 'http://194.105.111.10:8080/geoserver/higU1EU8kM6eJtKaHg14USMyTsQSOpP6/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=higU1EU8kM6eJtKaHg14USMyTsQSOpP6%3Acemetery_shape&TILED=true&WIDTH=256&HEIGHT=256&CRS=EPSG%3A4326&STYLES=&BBOX=22.5%2C67.5%2C33.75%2C78.75' 
from origin 'http://194.105.111.10:3000' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

我已经在 GeoServer web.xml 中启用了 CORS,我也在 Tomcat web.xml 中启用了 CORS,此外,这是我在 nodejs 中为 expressjs 和 nodejs 路由器设置的 CORS:

app.use(function (req, res, next) {

  // Website you wish to allow to connect
  res.setHeader("Access-Control-Allow-Origin", "*");

  // Request methods you wish to allow
  res.setHeader("Access-Control-Allow-Methods", "*");

  // Request headers you wish to allow
  res.header("Access-Control-Allow-Headers", "*");

  // Set to true if you need the website to include cookies in the requests sent
  // to the API (e.g. in case you use sessions)
  res.setHeader("Access-Control-Allow-Credentials", true);

 
  // Pass to next layer of middleware
  next();
});
  
app.use(cors({
  "origin": "http://194.105.111.10:3000",
  "credentials":true,
  "preflightContinue": false,
  "optionsSuccessStatus": 204
}))
    

我当前在 /opt/tomcat/webapps/geoserver/WEB-INF/web.xml 中对 GeoServer 的 CORS 设置

  <!-- Uncomment following filter to enable CORS in Tomcat. Do not forget the> -->
    <filter>
      <filter-name>cross-origin</filter-name>
      <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
      <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
      </init-param>
</filter>

    
my current CORS setting in Tomcat9.0.58 /opt/tomcat/conf/web.xml

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

尽管我确实在 Tomcat 和 GeoServer 和 Backend(nodejs) 中启用了所有 CORS 配置,但我会收到 CORS ERROR

我在http://194.105.111.10:3000 上运行 Reactjs 我的 nodejs 在 http://194.105.111.10:3001 上运行 我正在通过 vscode 在远程服务器(地址 194.105.111.10)上编辑代码

我的笔记本电脑操作系统是 LMDE v5 服务器信息: 操作系统:Debian 11 x64, 节点:16.x, 反应 17.x, 雄猫 9.0.58, Java v8, 地理服务器 2.20.2,

身份验证方法

在我想将 WMS 图层添加到地图之前,我在图层列表中创建了一个 svg 链接作为图层预览:

我在后端(nodejs)中通过axios做到了这一点,下面的代码给了我一个svg图像链接,我将在firnt-end(Reactjs)的表层中使用它(我认为有时这种方法会导致用户在后台登录到地理服务器)

await axios({
      method:"GET",
      url:`http://localhost:8080/geoserver/${geoName}/wms?service=WMS&version=1.3.0&request=GetCapabilities&layers=${geoName}:${layerName}&srs=EPSG:4326`,
     
      maxBodyLength: Infinity,

      headers:{
        "Access-Control-Allow-Origin":"http://194.105.111.10:3000",
        'Content-Type':'application/xml',
        'Accept':'application/xml',
     
      },
      auth:{
        username:  username,
        password: geopass,
      },

    }).then((response)=>{
    // console.log('response get Capabilities ', response.data)
    try{
      parseString(response.data,async function(err,result){
    //  console.log('capabilities result ',result["WMS_Capabilities"].Capability[0].Layer[0].Layer)
        const getLayerCapability =result["WMS_Capabilities"].Capability[0].Layer[0].Layer
    // console.log('getLayerCapability',getLayerCapability)
      await getLayerCapability.forEach(element=>{
        // log('element ', element)
         if(element.Name.includes(layerName)){
          // log('element BoundingBox ', element.BoundingBox[1]["$"])
         Object.assign(bbox,element.BoundingBox[1]["$"])
      
       
         }
        
       })
        
      })
    }catch(error){
      console.error('getSvgLayers Error ', error)
    }
     
    }).catch(error=>{
      console.error('error ', error)
    })

// //
      const url=`http://194.105.111.10:8080/geoserver/${geoName}/wms?service=WMS&version=1.3.0&request=GetMap&layers=${geoName}:${layerName}&bbox=${bbox.minx},${bbox.miny},${bbox.maxx},${bbox.maxy}&width=768&height=768&srs=${bbox.CRS}&styles=&format=image/svg&authkey=${authkey}`
      return url

我应该提到我通过 Reacjs package.json 中的代理将 Reactjs 连接到 Nodejs “代理”:“http://194.105.111.10:3001”

【问题讨论】:

  • 我在 LMDE 5 上使用 Microsoft Edge 稳定版,当我想在 tileloadfuntion 中添加授权标头时,我会收到 CORS 错误,我想如果我找到登录 GeoServer 的方法,这个问题将得到解决

标签: reactjs tomcat cors openlayers geoserver


【解决方案1】:

你解决了这个问题吗?正如我从您的配置中看到的那样,有一个错误。 当凭据支持为真时,您不能使用 * 作为来源。 您可以在此处检查高级配置: https://tomcat.apache.org/tomcat-9.0-doc/config/filter.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-29
    • 2013-02-01
    • 2016-11-24
    • 1970-01-01
    • 2012-11-09
    • 2015-10-02
    • 2021-09-06
    • 2019-12-07
    相关资源
    最近更新 更多