Nginx proxy_pass 代理需显式配置 Host 头、关键请求头及 HTTP/1.1 和连接头,避免 rewrite 干预 URI 编码,用 $request_uri 透传原始 URI,确保方法、路径、参数完整不被修改。

要让 Nginx 在 proxy_pass 代理过程中保持客户端原始请求方式(即方法、URI 编码、路径结构、查询参数等不被意外修改),核心不是“阻止解码”,而是避免引入干扰逻辑——Nginx 对 URI 的初始解码无法关闭,但后续转发行为完全可控。
确保原始请求方法和请求头不被覆盖
Nginx 默认会原样转发请求方法(GET/POST/PUT 等)和绝大多数原始请求头,但以下两点必须显式配置,否则关键信息会丢失:
-
Host 头必须透传:用
proxy_set_header Host $host;(或$http_host含端口),而不是默认的$proxy_host,否则后端看到的是 upstream 地址,可能触发 404 或错误跳转 -
不要依赖“自动转发”:Nginx 不会自动转发所有原始头,
Authorization、Cookie、X-Requested-With等需按需显式设置;敏感头如Authorization若无需后端鉴权,可不透传
保留原始 URI 编码与空格等特殊字符
客户端发送的 URI 必须是合法编码格式(空格为 %20,中文为 %E4%B8%AD 等),Nginx 收到后会做一次 RFC 解码,但只要不额外干预,这个解码结果会完整用于转发。关键控制点在 proxy_pass 写法:
- location 前缀匹配(如
location /api/)时,proxy_pass http://backend/;(结尾带/)→ 自动剥离/api/,转发剩余路径,原始编码保留 - 若写成
proxy_pass http://backend;(结尾无/)→ 整个匹配路径(含/api/)被拼接到 upstream 地址后,容易造成路径重复或粘连 - 绝对禁止在 location 中使用
rewrite或set $args修改 URI,否则可能触发二次编码/解码,破坏原始格式
透传原始请求路径与查询字符串
$request_uri 变量包含原始未解码的 URI(含 query string),适合记录日志或透传给后端做精确比对:
- 添加
proxy_set_header X-Original-URI $request_uri;,后端可通过该头拿到客户端发出的完整编码字符串 - 注意:
$uri是解码后的路径部分,$args是解码后的参数,二者拼起来 ≠$request_uri;若后端需严格还原原始请求,优先依赖X-Original-URI - query string 默认随 URI 一起转发,无需额外配置;但若用了
rewrite ... ?清空参数,就会丢失,应避免
适配 WebSocket 或长连接等特殊协议
某些请求方式(如 WebSocket 升级)依赖特定 header 和 HTTP 版本,Nginx 默认会清除或改写:
- 必须显式透传:
proxy_set_header Connection $http_connection;和proxy_set_header Upgrade $http_upgrade; - 启用 HTTP/1.1:
proxy_http_version 1.1; - 关闭缓冲:
proxy_buffering off;,防止响应体被截断或延迟


















