必须显式设置 default_type application/json 并用单引号包裹 json 字符串,同时 add_header content-type 'application/json; charset=utf-8',才能确保浏览器正确解析不下载、不乱码。

用 return 200 在 location 中返回自定义 JSON,关键不是“能不能”,而是“怎么写才不被浏览器当文件下载、不乱码、不报错”。Nginx 对 JSON 的返回有隐含约定,漏掉任一细节就容易出问题。
必须显式设置 default_type application/json
如果不加这行,Nginx 默认把响应体当二进制流处理,浏览器收不到 Content-Type: application/json,就会触发下载行为(尤其 Chrome/Firefox)。
- 写法固定:
default_type application/json; - 不能写成
default_type text/plain或留空 - 该指令必须出现在
return之前,且在同一 location 块内
JSON 字符串要用单引号包裹,且不能换行
Nginx 配置解析器对引号和空白很敏感。双引号会被 shell 或配置加载器提前截断;换行会导致 nginx -t 校验失败,提示 invalid number of arguments。
- 正确:
return 200 '{"status":"ok","data":123}'; - 错误:
return 200 "{\"status\":\"ok\"}";(双引号) - 错误:
return 200 '{ "status": "ok" }';(含空格或换行)
中文必须显式声明 UTF-8 编码
default_type application/json 只设 MIME 类型,不带 charset=utf-8。旧版浏览器(如 IE、部分 Electron 应用)会默认按 GBK 解析,导致中文变方块或问号。
- 推荐写法:
add_header Content-Type 'application/json; charset=utf-8'; - 不要用
charset utf-8—— 它只对text/*生效,对application/json无效 - 该
add_header必须和return在同一 location 内,且顺序无关紧要
支持简单变量拼接(非 JSON 拼接)
Nginx 的 return 支持用 set 定义变量后插值,但仅限字符串拼接,不能动态生成嵌套 JSON 结构。
- 可行:
set $uid $1; return 200 '{"id":'$uid',"type":"user"}'; - 注意:JSON 内部仍需单引号包裹整体,变量外露部分不加引号
- 不支持函数调用、JSON 编码或数组生成,复杂逻辑请用 Lua 或后端处理











