关于express:无法在node.js上设置代理

cannot set proxy on node.js

我在端口5550上有node.js 4.1.1和express.js 4.8.5。我在端口8080上也有geoserver 2.8.0。两台服务器都在同一台笔记本电脑上。

节点上的一个应用程序想要从geoserver访问一些地图数据,这些是Openlayers的详细信息

1
2
3
4
5
6
7
 source: new ol.source.TileWMS({
      url: 'http://localhost:8080/geoserver/mymap/wms?',
      crossOrigin: 'anonymous',
// I also tried  crossOrigin: 'localhost:8080/' and crossOrigin: 'localhost:5550/' but nothing

       params: {'LAYERS': 'mymap:layer, mymap:anotherLayer, FORMAT': 'image/png' ,'CRS': 'EPSG:3857'},
       serverType: 'geoserver'

在geoserver上设置cors或proxy不可能导致技术问题(旧的jetty core、对原始的hack-ish解决方案、旧的jetty版本的不可用的jars)。为了避免CORS和Access Control Allow Origins错误,我想在节点上设置一个代理。我只想使用节点,因为它更容易设置。

根据这个和前面的问题,我必须设置一个反向代理,所以

  • 我不在客户端上进行代理配置
  • geoserver通过节点反向代理得到服务,因此看起来有相同的起源(=不再有CORS问题)
  • 客户端希望访问geoserver,但通过节点访问知道它

我想我的概念是正确的,但我不知道如何实现。我选择了HTTP代理中间件来实现这一点。我在我的app.js上添加了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var proxyMiddleware = require('http-proxy-middleware');

    var proxy = proxyMiddleware('http://localhost:8080/geoserver', {
                    target: 'http://localhost:5550',
                    changeOrigin: true  
                });

var app = express();

app.use('/' , function (req, res) {
       res.render('index', { title: 'testing', head: 'Welcome Testing Area'});
    });

app.use(proxy);
app.listen(5550);

在控制台上,我看到了[HPM] Proxy created: /geoserver -> http://localhost:5550

但我还是得到了错误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. The response had HTTP status code 404.

我不明白如何实现这一点。请指出我的错误,或者如果我没有得到正确的概念。请帮助我理解。

谢谢

更新

这些是我打开浏览器控制台时看到的标题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
General
Remote Address:[::1]:8080
Request URL:http://localhost:8080/geoserver/mymap/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=mymap%3Aplanet_osm_polygon%2C%20mymap%3Aplanet_osm_line%2C%20mymap%3Aplanet_osm_roads%2C%20mymap%3Aplanet_osm_point&TILED=true&CRS=EPSG%3A3857&WIDTH=256&HEIGHT=256&STYLES=&BBOX=2269873.9919565953%2C4618019.500877209%2C2348145.508920616%2C4696291.017841229
Request Method:GET
Status Code:404 Not Found

Response Headers
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=iso-8859-1
Content-Length: 1408
Server: Jetty(6.1.8)

Request Headers
Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:el-GR,el;q=0.8,en;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:5550
Referer:http://localhost:5550/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36

  • 这里有类似的问题:gis.stackexchange.com/questions/4323/…我需要一些时间来尝试使用nodejs的反向代理。
  • 您应该使用不同的代理lib:stackoverflow.com/questions/22889417/…它们有1000多个星,而您的lib只有25个星…这里有一些关于libs的教程:blog.ccare.me/blog/2013/09/18/…试试看!


看起来您配置的代理不正确。

  • 混合使用普通代理配置和速记配置
  • 目标应该是地理服务器,而不是Express服务器。

以geoserver为目标的普通语法:

1
2
3
4
var proxy = proxyMiddleware('/geoserver', {
                 target: 'http://localhost:8080',
                 changeOrigin: true  
            });

或使用速记语法:

此配置与前一配置的行为完全相同。

1
2
3
var proxy = proxyMiddleware('http://localhost:8080/geoserver', {
                 changeOrigin: true  
            });

  • 我照你说的做了,但还是没什么。
  • 您可以提供对服务器的请求及其响应代码吗?
  • 你的意思是打开浏览器的控制台,复制/粘贴Response HeadersRequest Headers?这会提供你想要的信息吗?
  • 我想应该行
  • 看到我原来的问题,我加了标题。再次感谢
  • 您可以不使用代理直接访问图像吗?这个img网址是从哪里来的?是另一种反应吗?
  • 你的意思是把这个链接http://localhost:8080/geoserver/cultumap/wms?SERVICE=WMS&VER‌​SION=1.3.0&REQUEST=G‌​etMap&FORMAT=image%2‌​Fpng&TRANSPARENT=tru‌​e&LAYERS=cultumap%3A‌​planet_osm_polygon%2‌​C%20cultumap%3Aplane‌​t_osm_line%2C%20cult‌​umap%3Aplanet_osm_ro‌​ads%2C%20cultumap%3A‌​planet_osm_point&TIL‌​ED=true&CRS=EPSG%3A3‌​857&WIDTH=256&HEIGHT‌​=256&STYLES=&BBOX=22‌​69873.9919565953%2C4‌​696291.017841229%2C2‌​348145.508920616%2C4‌​774562.534805249从头部粘贴到浏览器上,看看它是否加载图像?不,我得了404。但是8080上的地理服务器工作正常,我只是以管理员身份登录
  • 地理服务器创建这些图像和这些URL。从Postgis获取数据。我不知道怎么做,对不起。在我最初的问题中,如果我把app.use(proxy); 放在app.use('/' , function (req, res) {...之前,我可以通过55508080访问geoserver。
  • 但是如果我去http://localhost:5550/,我就得到Error 404 - Not Found. No context on this server matched or handled this request. Contexts known to this server are: /javadoc ---> org.mortbay.jetty.servlet.Context@62afe8c5{/javadoc,file:/C:‌​/Program%20Files%20(‌​x86)/GeoServer%202.8‌​.0/javadoc} /geoserver ---> org.mortbay.jetty.webapp.WebAppContext@adb1021{/geoserver,fi‌​le:/C:/Program%20Fil‌​es%20(x86)/GeoServer‌​%202.8.0/webapps/geo‌​server/}
  • 我知道,在这个问题上,mymap和在cultumap上面的评论中说,但同样的,我犯了一个错别字。
  • @chimurai,geoserver在8080端口,webapp在5550端口,他想在5550子文件夹下代理geoserver。
  • 我想我看到了另一个配置错误。target应该是geoserver而不是express服务器。` var proxy=proxymiddleware('/geoserver',target:'localhost:8080',changeorigin:true);`
  • @Chimurai谢谢。我明白我是怎么搞砸的。让我休息一下,我会回来回答的
  • @我认为你应该用这个来编辑你的答案。
  • 我会更新答案。在提示@inf3rno:)之后才看到实际问题。
  • @Chimurai很抱歉我在我的链接上犯了一个错误。现在工作。检查我的答案,谢谢你的时间和努力。你就是那个创造了http-proxy-middleware的人吗?最后一件事,我可以理解这个概念。通过使用代码,我可以将请求从节点重定向到geoserver,还是通过节点从geoserver发送数据?


Chimurai是对的。最终对我起作用的是设置http-proxy-middleware

在我的电脑上,我现在有了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var proxyMiddleware = require('http-proxy-middleware');

var proxy = proxyMiddleware('http://localhost:5550', {
                 target: 'http://localhost:8080',
                 changeOrigin: true,
                 xfwd: true
            });

/*
the above can be replaced by chimurai's version :
var proxy = proxyMiddleware('/geoserver', {
                 target: 'http://localhost:8080',
                 changeOrigin: true  
            });
and will still work
*/

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')));

app.use('/', function(req, res, next) {
    httpProxy.createProxyServer({target:'http://localhost:8080'});
    next();
});

app.use(proxy);

app.listen(5550);

我在Openlayers代码中删除了这个crossOrigin: 'anonymous',,并修复了Openlayers链接上的一个拼写错误,现在工作正常。

我还试图通过在geoserver上设置代理来解决这个问题,但这是不可能的,因为geoserver运行的是一个旧的jetty版本,现在是eol,所以没有官方的解决方案来代理geoserver或升级它。

通过节点进行故障排除是最佳解决方案