Nginx 不支持直接根据 Content-Length 做条件拦截,但可通过 client_max_body_size 硬限制、map + $content_length 动态标记(仅限非 chunked 请求)、Lua 模块精准数值判断三种方式间接实现;推荐优先使用 client_max_body_size 并配合 error_page 自定义 413 页面。

Nginx 本身不支持直接根据 Content-Length 请求头的数值做条件拦截(比如“拒绝大于 10MB 的请求”),但可以通过组合内置变量、限制指令和错误处理机制,**间接、可靠地实现基于内容长度的请求拦截**。核心思路是:利用 client_max_body_size 做第一道硬性限制,再结合 map + if(谨慎使用)或日志/监控辅助判断,必要时用 Lua 模块增强控制力。
使用 client_max_body_size 实现基础拦截
这是最常用、最安全的方式,Nginx 在请求体读取前就依据 Content-Length 头或分块传输的边界做预判,超限时直接返回 413 Request Entity Too Large。
- 在
http、server或location块中配置:
client_max_body_size 5m;
- 该值会与请求中的
Content-Length比较(若存在且合法),超出即拦截;对 chunked 编码也生效 - 注意单位:可写
1k、10m、1g;设为0表示不限制(不推荐) - 若需自定义错误页,搭配
error_page 413 /413.html;
通过 map + $content_length 变量做动态策略(仅限已知长度)
Nginx 提供 $content_length 变量,它等于请求头中 Content-Length 的原始字符串值(如 "2048")。虽然不能直接用于数值比较,但可通过 map 映射为标记值,再配合 if 控制行为(注意:if 在 location 中有局限,慎用于重定向或 proxy_pass)。
- 示例:将超过 2MB 的请求标记为
deny,并返回 403
map $content_length $limit_flag {
default "";
"0" "";
~^[0-9]{1,7}$ ""; # ≤ 9999999 字节(约 9.5MB),粗略匹配
~^[0-9]{8,}$ "deny"; # ≥ 10000000 字节(≥ 9.5MB),视为超限
}
server {
location /upload {
if ($limit_flag = "deny") {
return 403;
}
# 后续正常处理...
}
}
- ⚠️ 注意:
$content_length在 chunked 请求中为空字符串,此法仅适用于明确带Content-Length的请求(如普通表单、JSON POST) - 正则匹配是字符串级的,非精确数值比较;如需严格判断,建议用 Lua
借助 Lua 模块(nginx-lua)实现精准数值拦截
若需严谨按字节数判断(包括解析 chunked、校验实际接收长度等),OpenResty 或编译了 ngx_http_lua_module 的 Nginx 是更优解。
- 示例:在请求头阶段检查
Content-Length是否超过 3MB
location /api {
access_by_lua_block {
local len = ngx.var.content_length
if len and tonumber(len) and tonumber(len) > 3 * 1024 * 1024 then
ngx.exit(413)
end
}
proxy_pass http://backend;
}
- 优势:支持完整数值运算、可结合
ngx.req.get_body_data()获取实际 body 长度(适合无Content-Length场景) - 要求:部署 OpenResty 或自行编译含 Lua 支持的 Nginx
补充建议:日志记录与可观测性
无论采用哪种方式,都建议记录原始 Content-Length,便于审计和调试:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$content_length"';
- 在 access log 中输出
$content_length,能快速识别异常大请求来源 - 配合 Prometheus + nginx-vts-exporter 等工具,可对高
Content-Length请求做告警











