nginx原生return返回json最简方案是两行:default_type application/json + return 200,缺default_type会导致浏览器下载文件;json须单引号包裹、不可换行,中文需charset utf-8防乱码。

直接用 return 返回 JSON 最简方案
不需要写后端、不依赖 Lua,Nginx 原生命令就能返回合法 JSON。关键就两行:default_type application/json + return 200。漏掉 default_type,浏览器会把响应当二进制文件下载(尤其 Chrome 和 Safari),这是最常踩的坑。
示例配置:
location /health {
default_type application/json;
return 200 '{"status":"ok","uptime":12345}';
}
注意点:
-
return后的 JSON 字符串必须用单引号包裹,双引号会和 Nginx 配置语法冲突 - JSON 内容不能换行,否则配置加载失败(报错
nginx: [emerg] invalid number of arguments in "return" directive) - 若含中文,建议加
charset utf-8或add_header Content-Type 'application/json; charset=utf-8',避免乱码
default_type 和 add_header Content-Type 的区别
default_type 是 Nginx 决定响应体 MIME 类型的兜底机制;而 add_header Content-Type 是强行覆盖响应头——但仅当响应体非空且未被其他模块提前设置时才生效。实际中优先用 default_type,更可靠。
错误写法(无效):
location /api {
add_header Content-Type application/json;
return 200 '{"msg":"hello"}'; # 此处 default_type 未设,Nginx 仍按 text/plain 发送
}
正确写法(推荐):
location /api {
default_type application/json;
return 200 '{"msg":"hello"}';
}
补充说明:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
-
charset utf-8是default_type的补充指令,它会自动在 Content-Type 后追加; charset=utf-8 -
add_header对return响应体有效,但对重定向(如return 302)无效,因为重定向无响应体
返回动态 JSON:用 set 提取 URL 参数拼接
纯静态 JSON 不够用?比如要根据请求路径返回不同字段,可用正则捕获 + set 变量拼接。注意:Nginx 变量拼接不支持 JSON 编码,所有转义、引号、结构需手动保证合法。
示例(从 /user/123 中提取 ID 并返回):
location ~ ^/user/(\d+)$ {
default_type application/json;
set $uid $1;
return 200 '{"id":'$uid',"type":"user"}';
}
关键限制:
- 正则捕获组最多 9 个(
$1–$9),$0是全匹配,不能用于set - 变量拼接时,字符串和变量之间**不能有空格**,否则 Nginx 解析为多个参数导致报错
- 无法做 JSON 数组、嵌套对象或字段存在性判断——这些必须交给后端或 Lua 模块
错误响应也得是 JSON:用 error_page + return
API 接口出错时返回 HTML 错误页很突兀。想让 404、429、500 也走 JSON 流程,得靠 error_page 映射到命名 location,再用 return 输出。
典型限流场景(429):
server {
error_page 429 = @rate_limited;
location @rate_limited {
default_type application/json;
return 429 '{"code":429,"message":"Too many requests"}';
}
}
注意事项:
-
error_page 429 = @xxx中的=表示内部重定向(不暴露给客户端),不可省略 - 命名 location(如
@rate_limited)里不能用root或alias,只允许return、add_header等有限指令 - 若上游代理(如
proxy_pass)返回了 502,而你又没配error_page 502,Nginx 会回退到默认错误页——这点极易被忽略
真正麻烦的不是怎么写 JSON,而是确保每个分支都显式设置了 default_type,且所有字符串拼接不破坏 JSON 结构。线上出问题时,第一反应不该是查后端日志,而是 curl -I 看响应头里的 Content-Type 是否真为 application/json。










