X-Original-URI用于透传客户端原始URI,需在rewrite前用$request_uri设置以保留完整路径和查询参数,配合X-Forwarded-For等头可重建原始请求上下文。

在 Nginx 反向代理中,proxy_set_header X-Original-URI 是一种常用手段,用于把客户端请求的原始 URI(即未被 rewrite 或 location 匹配重写前的路径)透传给后端服务。这对日志追踪、权限校验、路由分发等场景非常有用。
为什么需要保存原始 URI?
当 Nginx 使用 rewrite 指令或通过不同 location 块将请求重写/转发时,后端收到的 $uri 和 $request_uri 已是修改后的值。比如:
- 用户访问
/api/v2/users - Nginx 用
rewrite ^/api/v2/(.*)$ /v1/$1 break;改成/v1/users - 后端只看到
/v1/users,丢失了原始版本信息
此时,若后端需根据原始路径做灰度判断、审计或兼容处理,就依赖 X-Original-URI 这类自定义 header 传递上下文。
正确设置 X-Original-URI 的时机
关键原则:必须在任何 rewrite 或内部跳转发生之前捕获原始 URI,否则变量值已变。推荐在 server 或 location 最外层直接设置:
- 用
$request_uri—— 它保留协议、路径、查询参数完整字符串(含?后内容),适合完整还原 - 用
$uri—— 仅路径部分,不带查询参数,且已被解码,适合纯路径逻辑 - 避免用
$document_uri或$args单独拼接,易出编码或空格问题
示例配置:
location /api/ {
# 在 rewrite 前立即设置,确保原始性
proxy_set_header X-Original-URI $request_uri;
<pre class="brush:php;toolbar:false;">rewrite ^/api/v2/(.*)$ /v1/$1 break;
proxy_pass http://backend;
proxy_set_header Host $host;}
注意 URL 编码与后端接收一致性
$request_uri 是原始未解码的字符串(如 /path%20with%20space?q=a%26b),而后端语言(如 Python Flask、Node.js)通常自动解码。若后端需严格比对原始编码格式,可考虑:
- 改用
$uri?$args(但要注意$args为空时不补?,需用 map 或 if 判断) - 或统一约定后端对
X-Original-URI不再二次 decode - 测试时用
curl -v "http://x/api/v2/test%20a?k=v%2B1"验证 header 是否原样透传
配合其他 header 提升调试能力
单靠 X-Original-URI 有时不够,建议组合使用:
-
X-Forwarded-For:记录真实客户端 IP -
X-Forwarded-Proto:告知后端原始协议(http/https) -
X-Original-Method:用$request_method保存原始 HTTP 方法 -
X-Original-Host:用$host或$http_host记录原始 Host 头
这样后端可完整重建原始请求上下文,无需额外猜测或解析。


















