需先确认文件实际字节编码:VS Code用Reopen with Encoding测试,Linux/macOS用file -i和xxd查BOM,PowerShell用Get-Content -Encoding Byte;再保存为UTF-8无BOM,并确保紧贴开头且拼写准确。

直接改 meta charset 不一定能解决问题,关键得先确认文件实际字节编码,再同步修正保存方式和 HTML 声明。
怎么确认 index.html 实际是哪种编码?
别信编辑器右下角显示的“UTF-8”——那只是它“猜”的。真实编码藏在文件字节里:
- VS Code:用
Ctrl+Shift+P→ 输入Reopen with Encoding,依次试GBK、UTF-8、ISO-8859-1,哪个打开后中文不乱就是实际编码 - Linux/macOS 终端:
file -i index.html看输出里的charset=值;再用head -c 4 index.html | xxd检查开头是否为ef bb bf(即 BOM) - Windows PowerShell:
Get-Content index.html -Encoding Byte | Select -First 3,结果是239 187 191就代表有 UTF-8 BOM
保存为真正的 UTF-8(无 BOM)最稳妥
绝大多数现代浏览器和构建工具(Vite、Webpack)都默认按 UTF-8 解析,但讨厌 BOM —— 它会干扰 <meta charset="UTF-8"> 的识别,甚至让 Node.js 读取失败:
- VS Code:保存前按
Ctrl+Shift+P→Save with Encoding→ 选UTF-8(注意不是UTF-8 with BOM) - Notepad++:菜单栏
编码 → 转为 UTF-8 编码(不是“UTF-8-BOM”) - Sublime Text:菜单
File → Save with Encoding → UTF-8 - 保存后立刻用
xxd index.html | head -1验证开头不再有ef bb bf
<meta charset="UTF-8"> 必须放在 最开头
HTML 解析器只扫描前 1024 字节找 charset 声明,任何前置内容(包括空格、换行、注释、<script></script>)都可能导致它失效:
立即学习“前端免费学习笔记(深入)”;
- 正确位置:
<meta charset="UTF-8"> <title></title>——<meta>紧跟,前面不能有任何字符 - 常见错误:
<!-- 注释 --><meta charset="UTF-8">(注释挡路)、<p><meta charset="UTF-8"></p>(<p></p>不该在里) - 拼写必须严格:
UTF-8(带短横、大写 U T F、数字 8),utf8或UTF8都无效
本地双击打开(file://)时最容易忽略的一点
HTTP 协议头缺失,浏览器完全依赖 <meta charset> 和 BOM 判断编码。此时如果文件是 GBK 但写了 UTF-8,或有 BOM 但编辑器没识别准,就必然乱码:
- 双击打开前,务必用上面方法确认并统一:文件实际字节 = 保存编码 =
<meta charset>声明 - 如果必须支持双击,且无法改文件编码(比如遗留 GBK 文件),就只能把
<meta>改成<meta http-equiv="Content-Type" content="text/html; charset=GBK">,但这是妥协方案,不推荐新项目用 - 开发阶段尽量用
python -m http.server或 Vite 启服务预览,避免 file:// 的 fallback 行为干扰判断
BOM 是最隐蔽的坑:它看不见、删不掉(普通编辑器不显示),却能让整个 charset 声明失效。每次保存 HTML 前,多看一眼开头三字节,比反复刷新页面更省时间。



















