nginx 从1.13.2起支持$sent_trailer_*变量,用于捕获后端在trailer头声明并随chunked响应末尾发送的元数据(如x-process-time),需后端显式设置trailer头及对应字段值,变量名中短横线自动转为下划线,仅在响应阶段有效且空值为空字符串。

在支持分块传输编码(Chunked Transfer Encoding)的 HTTP 服务中,$sent_trailer_名称 是 Nginx 提供的变量,用于捕获后端响应中通过 Trailer 头声明、并在响应体末尾以 trailer 形式发送的自定义元数据。它常用于审计分块传输路径中动态附加的状态信息(例如处理耗时、校验摘要、重试次数等)。
确认 Nginx 版本与模块支持
该变量自 Nginx 1.13.2 起引入,需确保使用的是较新稳定版(推荐 ≥1.19.0),且编译时未禁用 http_ssl 和 http_v2 相关模块(虽非直接依赖,但 trailer 语义在 HTTP/2 中更严谨)。可通过以下命令验证:
-
nginx -v查看版本 -
nginx -V 2>&1 | grep -o 'trailer'若无输出,说明已支持(默认启用)
配置后端正确发送 Trailer
后端(如 Node.js、Python Flask、Go net/http)必须显式设置 Trailer 响应头,并在 chunked 响应结束前写入 trailer 字段。Nginx 不会自动提取任意 trailer,仅读取 Trailer 头中声明的字段名对应的值。
例如,后端需发送:
HTTP/1.1 200 OK Transfer-Encoding: chunked Trailer: x-process-time, x-checksum <p>...(分块数据)... 0\r\n x-process-time: 142\r\n x-checksum: sha256:abcd1234\r\n \r\n</p>
此时 Nginx 才能将 x-process-time 的值存入 $sent_trailer_x_process_time,下划线替代连字符。
在 log_format 中安全引用变量
在 log_format 中直接使用 $sent_trailer_* 变量即可,若 trailer 未发送,对应变量值为空字符串,不会报错:
log_format audit '[$time_local] $status $body_bytes_sent '
'"$sent_trailer_x_process_time" "$sent_trailer_x_checksum"';
注意:
- 变量名中的短横线(-)在 Nginx 内部自动转为下划线(_),所以 x-process-time → $sent_trailer_x_process_time
- 不建议在 access_log 指令中直接拼接未加引号的变量,避免日志解析歧义
结合 map 或 set 实现条件审计增强
可配合 map 指令将 trailer 值映射为更明确的审计标签,或用 set 进行空值兜底:
map $sent_trailer_x_process_time $audit_latency {
"" "unknown";
default $sent_trailer_x_process_time;
}
<p>log_format audit '... "$audit_latency" ...';</p>
也可在 location 块中用 set 定义中间变量,便于后续 rewrite 或 header 注入:
set $audit_checksum $sent_trailer_x_checksum; add_header X-Audit-Checksum $audit_checksum;
这有助于在日志之外同步透传状态元数据。
不复杂但容易忽略:trailer 必须由后端主动声明并发送,Nginx 不生成也不猜测;变量名转换规则和空值行为需实测验证;HTTP/1.1 分块响应中 trailer 支持度比 HTTP/2 更易出兼容问题,建议优先在 HTTP/2 环境下使用。











