nginx默认记录重定向后的最终请求信息,要记录原始请求需在rewrite或内部跳转前用set保存$orig_uri、$orig_args等变量,或用map在http块中预定义实现惰性冻结。

默认情况下,Nginx 的 $request、$uri、$args 等变量记录的是**重定向后最终处理的请求信息**(即 301/302 后的内部跳转目标),而不是用户最初发起的那个请求。要记录原始请求(跳转前的 URI、参数、方法等),需在重定向发生前就捕获并保存这些值。
使用自定义变量在 rewrite 或 return 前保存原始信息
Nginx 允许用 set 指令在请求处理早期(如 server 或 location 块中)保存原始值。只要确保它在任何 rewrite、return 或内部跳转之前执行即可:
- 在匹配原始请求的 location 中,立即用
set $orig_uri $uri、set $orig_args $args、set $orig_request $request等保存 - 后续即使发生 rewrite 或内部 redirect,这些变量值仍保持不变
- 再在 log_format 中引用这些变量,就能写入 access_log
配置示例:记录跳转前的完整原始请求行
在 http 或 server 块中定义日志格式,并在关键 location 中提前保存:
log_format original_log '$remote_addr - $remote_user [$time_local] '
'"$orig_request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'orig_uri:"$orig_uri" orig_args:"$orig_args"';
<p>server {
location /old-path/ {</p><h1>✅ 在 rewrite 前立即保存原始信息</h1><pre class="brush:php;toolbar:false;"> set $orig_request $request;
set $orig_uri $uri;
set $orig_args $args;
rewrite ^/old-path/(.*)$ /new-path/$1? permanent; # 301 跳转
}
location /new-path/ {
# 这里 $uri 已是 /new-path/...,但 $orig_* 仍保留跳转前值
access_log /var/log/nginx/redirect.log original_log;
# ...后续处理
}}
注意 internal 重定向与 try_files 的特殊性
对于 try_files 触发的内部重定向(如 try_files $uri @fallback),或 error_page 404 =301 /xxx 这类内部跳转,原始请求信息同样会丢失。此时也需在最外层 location 中提前 set:
- 把
set $orig_...放在包含try_files的 location 顶部 - 避免放在被内部跳转“绕过”的子块中(如 @named_location 内部)
- 若用
error_page触发跳转,原始请求变量在 error_page 指向的 location 中已不可用,必须在触发前保存
替代方案:用 map 提前映射(适合全局统一处理)
如果需要对多种跳转场景统一记录原始请求,可用 map 在 http 块中预定义变量,利用其惰性求值特性,在首次引用时取当前值:
map $request $orig_request { default $request; }
map $uri $orig_uri { default $uri; }
map $args $orig_args { default $args; }
<p>log_format original_log '"$orig_request" orig_uri:"$orig_uri"';
access_log /var/log/nginx/access.log original_log;</p>这种方式更简洁,且天然“冻结”了初始值,无需担心执行顺序,推荐优先使用。











