← 中文资源

简体中文版本

Nginx — 413 Request Entity Too Large

诊断被 Nginx 以 413 拒绝的上传,在代理和应用之间对齐 client_max_body_size,并返回清晰的 JSON 错误而不削弱限制。

阅读英文原文

413 来自代理,不是应用

Nginx 拒绝请求体时,请求根本没到应用。应用日志为空,响应是 Nginx 的 HTML 错误页而不是 API 的 JSON。默认 client_max_body_size 是 1 MB,这解释了为什么小文件成功、大文件失败。

location /api/upload {
    client_max_body_size 10m;
    proxy_pass http://app;
    proxy_request_buffering off;
}

把限制设在上传 location 上,而不是全局,以保护无关端点。如果前面还有 CDN 或 ingress,其限制也必须对齐。

对齐每一层

有效限制是请求路径中最小的那个。检查 ingress、Nginx、应用框架和对象存储策略。Nginx 允许 10 MB 而应用限制 5 MB 时,仍会在 5 MB 被拒绝,只是错误和日志来自另一层。

返回有用的错误

API 客户端需要可解析的响应。使用 error_page 413 = @json_413; 返回带 request id 的 JSON。不要返回客户端会误当 JSON 解析的通用 HTML 页面。记录拒绝时的内容长度和路由,但不要记录请求体。

保持限制安全

更大的上传限制会增加未认证滥用的暴露面。上传要求认证、限流、把大请求体流式写入磁盘,并在应用中再次校验大小。测试精确边界:刚好达到限制的文件应通过,多一个字节应以预期状态失败。

修复与验证

通过在上传 location 设置 client_max_body_size、对齐 ingress 和应用限制,并为 API 路由添加 JSON 错误页,修复有效限制。用刚好低于和刚好高于限制的文件验证,确认应用收到允许的请求,超大请求返回预期状态和内容类型。检查 Nginx 访问日志中的 request id,证明是哪一层拒绝的。