【问题标题】:node.js and geoserver CORSnode.js 和 geoserver CORS
【发布时间】:2015-12-25 17:47:45
【问题描述】:

我有 node.js 服务器 0.10.12 和 express.js 4.8.5。 Node.js 是 Web 服务器,包括 openlayers 3.9.0。

Geoserver 2.1.3 服务于 WMS 层。稍后,我将实现矢量图层。

只有一条路线(用于索引页面)

var routes = require('./routes/index');

index.js 包含

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.render('index', { title: 'openlayers3 testing', head: 'Welcome' });
  next();
});

module.exports = router;

所以app.js

var routes = require('./routes/index');//explained above

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

我为 CORS 添加了以下内容

app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
});


app.get('/', routes);

index.ejs 中,我将我的 Geoserver WMS 图层设置为这样

var ait = new ol.layer.Tile({
extent: textent,
source: new ol.source.TileWMS({
  url: 'http://localhost:8080/geoserver/mymap/wms',
  crossOrigin: 'anonymous',
  attributions: [new ol.Attribution({
    html: '&copy; ' +'<a href="http://www.geo.admin.ch/internet/geoportal/' +'en/home.html">' +'National parks / geo.admin.ch</a>'
  })],
   params: {'LAYERS': 'mymap:planet_osm_polygon, mymap:planet_osm_line, mymap:planet_osm_roads, mymap:planet_osm_point'},
   serverType: 'geoserver'
 })

})

我得到了错误

Image from origin 'http://localhost:8080' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5550' is therefore not allowed access.

我尝试了很多我在网上找到的变体。我将代码放在app.use(express.static(path.join(__dirname, 'public'))); 之前。我把它放在index.jsrouter.get 里面。依然没有。我不明白出了什么问题。

谢谢

笔记

这在 internet explorer 11 中有效。没有错误,我实际上可以看到图层

firefox 30 没有错误,但我看不到图层

在 chrome 45 中,我看不到图层并且出现了该错误

【问题讨论】:

  • @slevin 您在错误的一侧添加了 CORS。您正在从节点应用程序连接到您的地理服务器。因此,CORS 应该添加到您的 Geoserver 中,而不是 Node 应用程序中。
  • @JonatasWalker 是的,谢谢,我打算根据这个重新设置我的地理服务器
  • @ɦassansin 你好。我意识到这一点,你是对的。我现在阅读有关 CORS 的文章。但是,为了对话,假设我只能访问和设置node.js 而不是Geoserver。那我该怎么办?将代理设置为node.js?谢谢

标签: node.js express openlayers openlayers-3 geoserver


【解决方案1】:

忘记'Access-Control-Allow-Origin', '*' 这是一个巨大的安全风险。改为设置请求域的名称并维护域白名单。

我认为很明显您的中间件没有在http://localhost:8080 响应中设置标题。检查网络面板上的标题,萤火虫等......并调试它。 How to debug the http response headers from a HTTP call

Firefox 无法始终正确处理 CORS 错误,因此您也应该检查 chrome。 Internet Explorer 的工作方式与其他浏览器不同:https://stackoverflow.com/a/22450633/607033 所以它接受http://localhost:5550 作为同源,这就是为什么你的错误代码在 msie 中工作的原因。尝试通过附加主机文件来使用自定义命名域,我相信您也会收到来自 msie 的错误消息。

编辑 - 赶上 cmets

示例代码的主要问题是 webapp(域:http://localhost:5550)返回您的 CORS 标头。由于 webapp 想要从浏览器访问 geoserver (http://localhost:8080),geoserver 应该授予访问权限而不是 webapp。所以地理服务器应该返回 CORS 标头而不是 webapp。

根据 slevin 的说法,他们当前使用的 geoserver 版本是不可能的。添加反向代理并在 webapp 的子文件夹下提供地理服务器或在地理服务器的子文件夹下提供 webapp 的可能解决方法。这样,它们都将具有相同的起源。另一种选择坚持使用不同的域,但使用反向代理将 CORS 标头添加到地理服务器响应中。

【讨论】:

  • Chrome 控制台为来自localhost:8080 的地图提供200 状态,但没有大小。和CORS错误。 Firebug 还给出了200 状态,有大小,但没有错误。我不明白您所说的“我认为您的中间件显然没有在localhost:8080 响应中设置标头。检查网络面板、萤火虫等上的标头……并调试它。”。如果您想更新答案并向我解释,那就太好了,因为坦率地说,我是堆栈。
  • 我也红了http://jonathanmh.com/how-to-enable-cors-in-express-js-node-js/http://www.tamas.io/node-jsexpress-cors-implementation/,并尝试实现,但没有运气。谢谢
  • @slevin 根据您的错误消息,访问控制标头未显示在响应中,这会导致问题。我添加了一个关于如何使用 firebug 在 firefox 中检查响应标头的链接,但是您可以使用开发工具在任何当前浏览器中执行此操作。
  • @slevin 在我看来,您将访问控制标头添加到 localhost:5550 响应而不是 localhost:8080 响应的问题。我认为您并不完全了解 CORS 的工作原理。你应该阅读手册。 w3.org/TR/cors
  • @slevin 如果您的意思是从 5550 提供地理服务器,或者通过代理从 8080 提供您的 webapp,那么两者都可以。如果您可以将地理服务器放在第三个域的代理后面,那么您也可以添加允许来源标头。您应该要求 geoserver 开发人员在下一个版本中实现 CORS 标头功能。
【解决方案2】:

尝试使用禁用安全性并允许访问本地文件来启动 google-chrome

google-chrome --disable-web-security --allow-file-access-from-files

这将禁用同源策略并允许本地文件相互访问。

您可能会收到稳定性和安全警告,您可以在开发中避免这种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 2012-09-02
    • 2015-10-09
    • 1970-01-01
    • 2015-11-26
    • 2022-10-17
    • 2018-08-08
    相关资源
    最近更新 更多