答案是优先检查Response Headers中Content-Type是否含charset=utf-8,若缺失则问题在服务端或Web服务器配置;其优先级高于meta标签,且必须写为utf-8而非utf8等变体。

先看浏览器 Network 面板里的 Response Headers,Content-Type 有没有 charset=utf-8 —— 没有就直接卡在服务端或 Web 服务器配置上,不用往下查 meta 标签。
查 Content-Type 响应头是否生效
HTML 页面走 HTTP 协议时,Content-Type 响应头的优先级高于 <meta charset="UTF-8">。如果它写着 charset=gbk 或 charset=iso-8859-1,哪怕 <meta> 写得再标准也白搭。
- 用 Chrome/Firefox 打开 F12 → Network → 刷新页面 → 点 HTML 请求 → 查
Response Headers下的Content-Type - Nginx 默认不带 charset,需显式加
add_header Content-Type "text/html; charset=utf-8";(注意:不是charset utf-8;) - Express 中用
res.set("Content-Type", "text/html; charset=utf-8"),且必须在res.send()或res.sendFile()之前调用 - PHP 的
header("Content-Type: text/html; charset=utf-8")前不能有任何输出(包括 BOM、空格、换行)
确认 HTML 文件实际编码是不是 UTF-8
编辑器显示 “UTF-8” 不代表文件真是 UTF-8。VS Code 右下角标着 UTF-8,但可能是它强行按 UTF-8 解码了一个 GBK 编码的文件,结果全是乱码。
- Linux/macOS 终端执行:
file -i index.html,看输出里charset=后面是什么 - 检查 BOM:执行
head -c 3 index.html | xxd,输出ef bb bf表示有 UTF-8 BOM;有 BOM 时,<meta charset>必须紧贴<head>开头,否则可能被跳过 - Windows PowerShell:运行
Get-Content index.html -Encoding Byte | Select -First 3,若输出239 187 191就是 BOM - VS Code 中点击右下角编码名称 → 选
Reopen with Encoding→ 依次试GBK、UTF-8、ISO-8859-1,看哪一种能正常显示中文
验证 <meta charset> 是否位置正确且写法规范
这个标签只有两个硬性要求:必须在 <head> 内、必须出现在所有其他标签(包括注释和空白)之前。任何前置内容都可能导致浏览器忽略它。
立即学习“前端免费学习笔记(深入)”;
- 打开 Elements 面板,展开
<head>,确认<meta charset="UTF-8">是第一个子节点,前面没有<!-- -->、空格、零宽字符(如U+200B) - 只认
UTF-8(大小写敏感),utf8、UTF8、utf-8都无效 - 不要混用:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">是 HTML4 写法,HTML5 已不推荐,且和<meta charset>同时存在可能引发解析歧义 - 双击本地打开(
file://协议)时,HTTP 响应头不存在,此时完全依赖<meta charset>,所以更要确保它位置绝对靠前
真正容易被忽略的是:BOM 和 <meta charset> 的位置冲突。哪怕只多一个看不见的空格或注释,浏览器扫描前 1024 字节时就找不到 charset 声明,会 fallback 到系统默认编码(Windows 是 GBK),然后整页中文全崩。这不是 bug,是规范行为。



















