nginx不支持原始idn域名,需用punycode编码后配置server_name;浏览器自动转换idn为punycode发送,nginx仅做字符串匹配;https证书也需用punycode申请。

Nginx 本身不直接支持原始格式的国际化域名(IDN),比如 中文.中国 或 café.fr 这类含非 ASCII 字符的域名。它只接受 ASCII 编码的域名字符串进行 server_name 匹配。但你可以通过 Punycode 编码转换,让 Nginx 正常识别和路由 IDN 请求。
✅ 正确配置 IDN 的核心步骤
- 用户访问
中文.中国→ 浏览器自动转成xn--fiqs8s.xn--fiq228c→ DNS 解析 → 请求发到你的服务器 → Nginx 用 Punycode 形式匹配server_name
所以你必须在 server_name 中填写 Punycode 编码后的域名,而不是原始中文或带重音符号的字符串。
如何获取 Punycode 编码?
你可以用以下任一方式快速转换:
在线工具:https://www.php.cn/link/993ae4a1829d8e9cea9eb96b3c83e648 或 https://www.php.cn/link/ae76e0ce35acf5be4b5960362281753d
-
命令行(Linux/macOS):
# 安装 idn 工具(Ubuntu/Debian) sudo apt install -y idn # 转换 idn "中文.中国" # 输出:xn--fiqs8s.xn--fiq228c
示例配置(支持中文域名)
server {
listen 80;
server_name xn--fiqs8s.xn--fiq228c; # ← 必须是 Punycode 格式
root /var/www/zh-cn;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
⚠️ 注意:Nginx 不会自动解码 Host 头里的 Punycode;客户端(浏览器、curl 等)负责把用户输入的 IDN 转为 Punycode 发送,Nginx 只做字符串匹配。
? 补充:同时支持 ASCII 和 IDN(推荐)
很多网站既要 example.com,又要 示例.中国,可以写多个 server_name:
server {
listen 80;
server_name example.com xn--fsq.xn--fiq228c; # www.example.com + 示例.中国
root /var/www/main;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
只要 DNS 已将这两个域名都解析到同一台服务器 IP,Nginx 就能统一处理。
❌ 常见误区
- 直接写
server_name 中文.中国;→ Nginx 启动失败(报错invalid server_name) - 期望 Nginx 自动识别并转换 IDN → 不支持,必须手动转 Punycode
- 忘记配置 DNS A/CNAME 记录指向服务器 → 即使 Nginx 配对了,用户也访问不到
? HTTPS 场景下额外注意
如果你用 Let’s Encrypt(certbot)申请 IDN 域名证书:
- certbot 支持 Punycode 域名,但必须用 Punycode 形式申请:
certbot --nginx -d xn--fiqs8s.xn--fiq228c
- 浏览器显示仍是
中文.中国(证书链和 UI 层自动还原),不影响用户体验。
不复杂但容易忽略











