在 nginx 中,使用 addition 模块(通常指第三方模块 ngx_http_addition_module)可以在响应正文的头部和尾部追加内容。具体做法是启用该模块后,配置 addition_types 指定需要处理的 mime 类型,并使用 add_before_body 和 add_after_body 指令指向包含待追加内容的本地文件。nginx 会先获取目标资源,再读取这两个文件的内容,将它们分别插入到原始响应的开头和结尾,最后合并输出给客户端。

如何配置基本的前后置注入功能
要实现基本的响应前后追加,需要在 http、server 或 location 块中设置三个关键指令:addition_types 定义触发追加的 MIME 类型,add_before_body 指定前置文件的 URI,add_after_body 指定后置文件的 URI。这些指令支持通配符 * 以匹配所有类型,但为了性能建议明确指定如 text/html。当请求匹配该 location 时,Nginx 内部会按顺序执行:获取原始内容 -> 读取前置文件 -> 读取原始内容 -> 读取后置文件 -> 合并发送。

server {
listen 80;
server_name example.com;
# 指定需要追加内容的 MIME 类型
addition_types text/html application/json;
location /api/data {
proxy_pass http://backend;
# 在响应头之后、主体之前插入 HTML 片段
add_before_body /static/injection/header.html;
# 在响应主体之后插入统计脚本
add_after_body /static/injection/footer.html;
}
}
上述配置中,addition_types 限制了只有 text/html 和 application/json 类型的响应才会被处理。如果后端返回的是图片或其他二进制流,Nginx 将直接透传,不会进行追加操作。add_before_body 和 add_after_body 指向的文件必须是 Nginx 可访问的静态文件,且路径相对于 Nginx 的配置上下文。这种机制允许在不修改后端应用代码的情况下,动态注入广告、统计代码或警告横幅。
如何处理嵌套 Location 与优先级冲突
当 Nginx 配置中存在多个 location 块或嵌套结构时,addition 模块的行为遵循标准的 Nginx 继承规则。子 location 块中的指令会覆盖父级 location 或 server 块中同名的指令。如果未在子块中显式声明 add_before_body 或 add_after_body,则继承父级的设置;若声明为空值(即不赋值),则会禁用从父级继承的追加行为。此外,addition_types 同样遵循此覆盖逻辑,这意味着你可以为不同的 URL 路径配置不同的追加策略。

server {
listen 80;
server_name example.com;
# 全局默认:所有 HTML 都追加页脚
addition_types text/html;
add_after_body /static/global/footer.html;
location /public {
root /var/www/html;
# 继承全局的 add_after_body
}
location /admin {
root /var/www/admin;
# 覆盖全局设置:添加特定的管理页眉
add_before_body /static/admin/header.html;
# 禁用全局页脚
add_after_body "";
}
}
在上面的示例中,访问 /public 下的 HTML 页面会看到全局定义的页脚,因为子 location 没有重新定义 add_after_body。而访问 /admin 下的页面时,由于显式设置了 add_before_body 并清空了 add_after_body,最终响应将只包含管理员专用的页眉,而不包含全局页脚。这种灵活性使得管理员可以为不同业务模块定制响应结构。需要注意的是,如果 add_before_body 或 add_after_body 指向的文件不存在,Nginx 默认会返回 404 错误,除非配置了 error_page 来处理这种情况,否则整个请求可能会失败。
当追加文件过大或后端返回压缩内容时会发生什么
如果配置的追加文件体积较大,或者后端响应启用了 Gzip 压缩,addition 模块的处理行为会有显著差异。对于大文件,Nginx 会将整个前置和后置文件加载到内存缓冲区中,然后与原始响应体合并。这会增加 Nginx 进程的内存占用,并在高并发下可能影响性能。更关键的是,如果后端返回的是 Content-Encoding: gzip 的压缩内容,而 addition 模块未配合 ngx_http_gunzip_module 使用,追加操作将在压缩后的二进制数据上进行,导致生成的响应损坏,浏览器无法解析。因此,在使用追加功能时,必须确保后端返回的是未压缩的明文内容,或者在 Nginx 层面先解压缩再进行追加,最后再重新压缩(但这通常需要更复杂的配置或自定义模块)。


















