Nginx必须透传后端Content-Type中的charset参数,禁用proxy_hide_header Content-Type,改用proxy_set_header Content-Type $upstream_http_content_type;原样保留;若后端未设charset,须在微服务侧修复,Nginx无法补全。

关键不是“加 Content-Type”,而是让 Content-Type 中的 charset=utf-8 不被 Nginx 丢掉或覆盖——后端微服务依赖这个信息决定用什么编码解析请求体,比如中文参数、JSON 字段值、表单数据。
必须透传并保留原始 charset
Nginx 默认会“净化”上游响应头,尤其 Content-Type 中的 charset 参数常被剥离。例如后端返回 Content-Type: application/json; charset=utf-8,Nginx 可能只转发 application/json,导致前端或下游服务按默认编码(如 ISO-8859-1)解码,中文变乱码。
- 禁用自动清理:不要用
proxy_hide_header Content-Type,它会直接删掉整个头 - 显式透传:用
proxy_set_header Content-Type $upstream_http_content_type;,原样保留后端设置的完整值 - 若后端未设 charset(比如 Spring Boot 默认不带),则必须在微服务侧修复,Nginx 无法补上
针对表单类请求主动声明 charset
POST 表单(application/x-www-form-urlencoded 或 multipart/form-data)的请求体编码,浏览器通常不带 charset,但后端(如 Spring MVC、Tomcat)需明确知道该用 UTF-8 解析。
- 强制设置:
proxy_set_header Content-Type "application/x-www-form-urlencoded; charset=utf-8"; - 仅适用于确定是表单提交的 location,避免误用于 JSON 接口
- 搭配
proxy_set_header Accept-Charset "utf-8";,提示后端“客户端支持且期望 UTF-8”
检查并统一微服务自身编码配置
Nginx 只是管道,真正决定编码的是微服务运行环境:
- Spring Boot:确保
server.servlet.encoding.charset=UTF-8和server.servlet.encoding.enabled=true已启用 - Tomcat:Connector 配置中加上
URIEncoding="UTF-8",否则路径和查询参数中的中文仍会乱码 - Java 应用读取 request.getParameter() 前,需调用
request.setCharacterEncoding("UTF-8")(Filter 中统一做) - Node.js / Python 微服务也需确认 bodyParser 或对应中间件默认使用 UTF-8
验证是否生效的简单方法
别只看浏览器页面,用 curl 直接查响应头和内容:
-
curl -I http://your-domain/api/xxx看响应头是否有Content-Type: ...; charset=utf-8 -
curl -v http://your-domain/api/xxx查看 raw response body 是否为合法 UTF-8 字节(可用iconv -f utf-8 -t utf-8//strict检验) - 对比直连微服务(绕过 Nginx)与走 Nginx 的响应头差异,快速定位是否被修改


















