nginx限流返回自定义json需两步:先用limit_req触发限流,再通过error_page跳转至named location,用return输出json;必须设default_type application/json且location需加internal。

要在 Nginx 限流触发时返回自定义 JSON 错误提示,核心是两步:一是用 limit_req 触发限流判断,二是用 error_page + named location + return 拦截并输出结构化 JSON。Nginx 默认返回 503 HTML 页面,必须显式覆盖才能得到标准 JSON 响应。
配置限流区域和触发规则
在 http 块中定义共享内存区,基于 IP 或其他键做速率控制:
-
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;—— 每个 IP 每秒最多 5 个请求 - 在
location /api/中启用限流:limit_req zone=api burst=10 nodelay; - 加
limit_req_status 429;显式设为语义更准确的 429 状态码(非必需,但推荐)
拦截 429 并返回 JSON 响应体
不能直接在原 location 写 return,必须通过命名 location 实现:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 用
error_page 429 = @rate_limited;把限流拒绝跳转到内部处理块 - 定义
location @rate_limited { internal; ... },internal防止被外部直接访问 - 在其中设置响应类型:
default_type application/json;(比add_header更可靠) - 用
return 429 '{"code":429,"msg":"Too many requests","retry_after":60}';输出 JSON 字符串 - 注意:JSON 必须用单引号包裹整个字符串;双引号无需额外转义;内容不能换行
常见踩坑点和优化建议
这些细节不处理好,JSON 可能无法正常解析或被浏览器下载:
- 漏掉
default_type application/json→ 浏览器可能把响应当二进制文件下载 - 在非
internallocation 中使用return处理 429 → 配置加载失败或行为异常 - 想动态插入变量(如
$request_uri)→ 可以用,例如:'{"path":"$request_uri","code":429}' - 需要带中文或特殊字符 → 加
charset=utf-8,写成default_type application/json; charset=utf-8; - 若 JSON 内容复杂或需服务端渲染 → 不建议硬编码,应交由后端统一处理,Nginx 仅作反向代理
替代方案:复用 503 错误页(兼容旧配置)
如果不想改状态码,也可拦截默认的 503:
error_page 503 = @rate_limit_json;location @rate_limit_json { internal; default_type application/json; return 503 '{"error":"rate_limited"}'; }- 语义不如 429 清晰,但对某些老旧客户端更兼容










