OpenLayers的crossOrigin参数会使图层消失。

3

这是我在openlayers中见过的最奇怪的行为。

我创建了一个jsfiddle来演示这个问题。

奇怪的行为是: 一旦我给我的图层添加crossOrigin参数,图层就会消失,你可以在jsfiddle中尝试(需要再次启用crossOrigin参数)。或者在下面查看:

var map = new ol.Map({
  target: 'map',
  layers: [

  ],
  view: new ol.View({
    projection: 'EPSG:4326',
    maxZoom: 25,
    center: [8.86, 54.13],
    zoom: 10,
  })
});

var wmsSource = new ol.source.TileWMS({
    preload: Infinity,
  url: 'http://service.gdi-sh.de/WMS_SH_BDDcol_KF?',
  params: {
    'LAYERS': 'DTK5col,DTK25col,DTK50col,DTK100col,UEK250,UEK600,UEK1500',
    'TILED': true,
    'STYLES': new String(''),
    'FORMAT': 'image/jpeg',
    'SRS': 'EPSG:4326',
    'VERSION': '1.1.1'
  },
  serverType: 'geoserver',
  //crossOrigin: 'anonymous' //<-- as soon as I enable this line, the layer dissappers
});

var wmsLayer = new ol.layer.Tile({
    source: wmsSource
})

map.addLayer(wmsLayer);

我需要使用crossOrigin参数来避免forEachLayerAtPixel()出现另一个问题:

https://gis.stackexchange.com/questions/269937/openlayers-4-method-foreachlayeratpixel-throws-securityerror-the-operation-is

解决方案就是在所有的图层中添加crossOrigin参数,这对于我拥有的所有其他图层都有效,但对于这个图层来说,它会使图层消失。
更有趣的是:如果我在火狐浏览器上打开调试并查看发送到服务器的请求。它的状态为200,并且所有图片都已成功加载(您甚至可以在网络分析中看到图片)。
所以我想知道,如果图层可以加载并且图片也在那里,是什么导致了图层的消失?只要我取消带有crossOrigin的行,一切就恢复正常。
2个回答

4

当WMS服务器没有启用CORS,或者从https应用程序尝试访问http服务器url时就会发生这种情况。您仍然可以加载它而不使用crossOrigin参数,但是图像将被污染。首先尝试将WMS url从http更改为https,但如果不起作用,则需要使用同一来源(或启用CORS)代理。要确保正确传递WMS参数,您需要在加载时对瓷砖URL进行URI编码,例如:

var wmsSource = new ol.source.TileWMS({
    preload: Infinity,
  url: 'http://service.gdi-sh.de/WMS_SH_BDDcol_KF?',
  params: {
    'LAYERS': 'DTK5col,DTK25col,DTK50col,DTK100col,UEK250,UEK600,UEK1500',
    'TILED': true,
    'STYLES': new String(''),
    'FORMAT': 'image/jpeg',
    'SRS': 'EPSG:4326',
    'VERSION': '1.1.1'
  },
  serverType: 'geoserver',
  crossOrigin: 'anonymous',
  tileLoadFunction: function(imageTile, src) {
    imageTile.getImage().src = 'myproxy.php?url=' + encodeURIComponent(src);
  }
});

我已经检查了您使用的WMS服务 - 它在http或https中都没有启用CORS,因此您绝对需要使用代理。


首先感谢您的回答。但是很遗憾,我对您在示例中编写的 titleLoadFunction() 不太熟悉。您能否向我解释得更详细一些? - Min XIE
它允许您覆盖OpenLayers用于加载瓦片所使用的图像对象的url。默认操作是 imageTile.getImage().src = src;其中= src是正常的瓦片url。但是,如果您正在使用代理,您需要将其更改为代理url并将正常瓷砖url作为代理参数。在javascript中设置图像源url的方法可以在此处找到:https://www.w3schools.com/jsref/prop_img_src.asp。 - Mike

1
问题发生的原因是服务器(在您的情况下,jetty)没有启用CORS。因此,您应该更改服务器的配置。请执行以下两个步骤:
  • 下载此文件并将其放置在Geoserver安装文件夹下的webapps\geoserver\WEB-INF\lib目录中(您应该使用与您的jetty兼容的文件,因此您可以从这里找到另一个合适的库)。

  • 转到webapps\geoserver\WEB-INF并打开web.xml文件。取消注释这两个标签。

这样做:

  <filter>
      <filter-name>cross-origin</filter-name>
      <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
  </filter>

和这个

  <filter-mapping>
      <filter-name>cross-origin</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

现在停止并重新启动Geoserver,以验证问题是否已经解决。

当您使用像Schleswig-Holstein地区政府地理门户网站这样的公共来源时,更改服务器设置不是一个选项。 - Mike
那么你应该联系他们来这样做。如果你想使用别人服务器上发布的服务,他们必须先通过在他们的服务器上启用CORS来允许你从其他域名访问该服务。 - Omid Reza Abbasi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接