代理转发后,WMS 的查询参数全丢了
直连 GeoServer 正常,经过公司网关后所有请求都变成“缺少 LAYERS 参数”,服务端日志里看不到 BBOX。
现象
浏览器请求的 URL 参数齐全,GeoServer 返回的参数却只剩一部分,或者完全是空的:
<ServiceException code="MissingParameterValue">
Could not find the LAYERS parameter
</ServiceException>
在 Nginx 访问日志里把 $request 打出来,参数是完整的,
说明丢失发生在转发阶段。
原因
proxy_pass 后面带 URI 时,Nginx 会用这个 URI 替换掉原始请求的路径与查询串。
例如 proxy_pass http://backend/wms;,原请求的
?SERVICE=WMS&... 会被丢弃。
使用 rewrite ... ? 显式给了新的查询串时,也会覆盖原参数;
而 rewrite 里如果写了 ? 结尾,同样会清空。
另一类问题是参数被二次编码,& 变成 &,
后端只解析到第一个参数。
排查过程
在 location 里临时打开请求日志,对比进入与转发的内容:
location /geoserver/ {
proxy_pass http://127.0.0.1:8080/geoserver/;
access_log /var/log/nginx/gis_proxy.log custom;
}
# log_format custom '$remote_addr "$request" -> $upstream_addr $upstream_status';
也可以把上游收到的完整 URI 打出来:
add_header X-Debug-Upstream $upstream_http_x_original_uri always;
解决方案
需要保留原始路径与参数时,proxy_pass 不要带 URI,
只写上游主机与端口:
location /geoserver/ {
proxy_pass http://127.0.0.1:8080; # 正确:不带 /geoserver
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
必须改写路径时,用命名捕获并显式带上 $is_args$args:
location /gis/ {
rewrite ^/gis/(.*)$ /geoserver/$1 break;
proxy_pass http://127.0.0.1:8080$uri$is_args$args;
}
前端拼接 URL 时不要手动 encodeURIComponent 整个查询串,
只对参数值编码,避免 & 被转义:
var params = new URLSearchParams({
SERVICE: 'WMS',
VERSION: '1.1.1',
REQUEST: 'GetMap',
LAYERS: 'workspace:roads',
BBOX: bbox.join(','),
WIDTH: 512,
HEIGHT: 512,
SRS: 'EPSG:3857',
FORMAT: 'image/png'
});
var url = '/geoserver/wms?' + params.toString();
验证
用 curl 经过代理请求,GeoServer 的访问日志里能看到完整的
LAYERS、BBOX、WIDTH。
GetMap 返回 PNG 而不是 XML 报错。
带多个参数的请求与只带一个参数的请求都正常。
一句话规则:proxy_pass 末尾有没有斜杠,决定路径是否被替换。
带 URI 就替换,不带就原样转发。参数丢失几乎都能从这一条找到原因。
经纬志(2026)。《代理转发后,WMS 的查询参数全丢了》。https://www.jingweizhi.com/cookbook/nginx-proxy-drop-params.html(访问日期 2026-11-03)。