You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止Nginx对重写后的URI进行自动编码?

Nginx rewrite 特殊字符自动编码问题解决方案

问题现象

当前使用的nginx.conf配置如下:

rewrite ^ $args?;
rewrite url=(.*) "$1" break;
proxy_pass http://proxy_backend;

规则匹配得到的$1取值为类似https://google.com/?arg=value的URL,需要将该值原样传递给proxy_backend后端服务,但实际Nginx转发的请求为GET https://google.com/%3Farg=value,URL中的问号被自动编码为%3F。

问题原因

Nginx解析rewrite规则替换字符串时,仅会识别替换串里**字面量写入的?**作为URI路径与查询参数的分隔符。如果?是从捕获变量(如当前配置里的$1)中读取的内容,Nginx会将其判定为路径段的非法普通字符,自动做URL编码转义为%3F,不会将?后的内容识别为查询参数。

修复配置(兼容所有Nginx稳定版本)

核心思路是提前拆分捕获值里的路径段和查询参数段,避免变量中携带的?被误识别为路径字符,和原配置逻辑完全对齐:

# 对齐原配置第一行rewrite的逻辑,清空原有请求参数
set $args '';
# 正则拆分url参数值:分别捕获不含?的路径部分、?后的查询参数部分
if ($args ~* url=([^?]+)(?:\?(.*))?$) {
    set $proxy_uri_path $1;
    set $proxy_uri_args $2;
    # 字面量写?,告知Nginx此处为路径和参数的分隔点,清空原有冗余参数
    rewrite ^ $proxy_uri_path? break;
    # 把拆分出的查询参数赋值给内置参数变量,转发时会自动正确拼接
    set $args $proxy_uri_args;
}
proxy_pass http://proxy_backend;

效果说明

配置重载后,Nginx转发的请求会自动将查询参数拼接到路径后,不会对?做编码,最终转发的请求行格式为GET https://google.com/?arg=value,符合原样传递的要求。

注意:如果你的Nginx版本高于1.17.9,也可以通过变量直接传给proxy_pass实现相同效果,上述配置是兼容性最高的通用方案,不需要依赖第三方模块或高版本特性。

内容的提问来源于stack exchange,提问作者user19327611

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:06:24