核心问题是请求路径、Nginx URI解析、FastCGI参数拼接、PHP接收视角四者未全程对齐UTF-8;需确保URL为标准UTF-8百分号编码,用$document_root$fastcgi_script_name拼接SCRIPT_FILENAME,统一文件名与系统locale为UTF-8。

FastCGI 场景下中文路径或参数乱码,核心问题不在 Nginx 本身是否“支持中文”,而在于 请求路径字节流、Nginx 的 URI 解析逻辑、FastCGI 参数拼接方式、PHP(或其他后端)接收时的编码视角 四者是否全程对齐 UTF-8。错一个环节,就可能 404 或显示为 。
确保请求 URL 是标准 UTF-8 百分号编码
浏览器地址栏输入 /测试.php 会自动转成 /%E6%B5%8B%E8%AF%95.php —— 这是合法 UTF-8 编码。Nginx 的 location 匹配发生在解码之后,所以必须确认它收到的是正确字节:
- 用
curl -v "http://localhost/%E6%B5%8B%E8%AF%95.php"测试,不要用curl -v "http://localhost/测试.php"(curl 可能按本地 locale 编码,不可靠) - 在 log_format 中加入
$request_uri $uri,对比原始未解码与解码后路径,确认中间没被二次转义 - 禁用可能干扰的模块,如旧版
ngx_http_sub_module,它可能对已解码的$uri再做字符串替换
避免 SCRIPT_FILENAME 拼接导致的编码错乱
这是 FastCGI 中最隐蔽也最常见的乱码根源。很多配置写成:
❌ 错误写法(硬拼接,风险高)fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
若 $fastcgi_script_name 含中文且来源路径本身是 GBK 字节(比如从 Windows 拷贝来的文件),拼出来就是乱码路径,PHP 找不到文件直接 404。
✅ 正确做法是使用 $document_root$fastcgi_script_name:
- 它依赖
root或alias指令定义的真实路径,不引入额外编码逻辑 - 前提是你的文件名在磁盘上确实是 UTF-8 编码(可用
ls -b验证:显示\346\226\207类似格式才是 UTF-8) - 如果已有 GBK 文件名,先用
convmv -f gbk -t utf-8 -r --notest /path/to/dir转码
统一 FastCGI 传递的环境变量编码
除了 SCRIPT_FILENAME,其他参数如 QUERY_STRING、REQUEST_URI 也要保持 UTF-8 视角一致:
- 确保 Nginx 配置中没有对
$args或$query_string做手动set或rewrite,避免隐式重编码 - PHP 端不要用
urldecode()多余处理$_SERVER['QUERY_STRING']—— Nginx 已完成解码,重复解码会损坏 UTF-8 字节 - 如需调试,可在 PHP 中打印
bin2hex($_SERVER['REQUEST_URI']),确认收到的是合法 UTF-8 十六进制序列(如e6b58b而非b2e2)
补充:系统 locale 与文件系统无关,但影响工具行为
Linux 文件系统只存原始字节,不存“编码类型”。但 convmv、iconv、甚至某些 shell 命令的行为受 $LANG 影响:
- 设
export LANG=en_US.UTF-8或zh_CN.UTF-8,避免终端误判文件名编码 - 不要在 Windows CMD(GBK)下直接创建含中文目录并挂载到 Linux,否则文件名是 GBK 字节,Nginx 按字节匹配失败
- 上传工具(如 Xftp)务必设为 UTF-8 编码模式,否则上传即乱码


















