必须位于第一个子元素,否则浏览器在前1024字节内找不到它,将fallback至ISO-8859-1或GBK等默认编码解析等内容,导致中文乱码且不可逆;注释、空格、BOM均会使其失效。

meta charset 必须放在 的最开头,紧挨着 标签之后、任何其他标签(包括 <title></title>)之前——否则浏览器可能已经用错误编码解析了部分 HTML,乱码就发生了,且无法回滚。
为什么 meta charset="UTF-8" 一定要放第一行?
浏览器解析 HTML 时,只在前 1024 字节内查找 meta charset;如果这范围内没找到,就会 fallback 到默认编码(通常是 ISO-8859-1 或系统本地编码,比如 GBK)。一旦开始解析 <title></title> 里的中文,而此时还没读到 meta,那些汉字就按错误编码解码了——后续即使补上 meta 也救不回来。
- 错误位置:
<title>你好</title> <meta charset="UTF-8">→你好很可能已乱码 - 正确位置:
<meta charset="UTF-8"> <title>你好</title> - 连注释或空格都不能插在中间:
<!-- 注释 --><meta charset="UTF-8">也会失效(某些旧版 IE)
charset 声明和文件实际编码必须一致
写了 meta charset="UTF-8" 却用记事本保存成 GBK,等于告诉浏览器“请用 UTF-8 解码”,但实际字节是 GBK 编码的——结果就是 ä½ å¥½ 这类乱码。这不是浏览器 bug,是你自己把“说明书”和“货物”搞错了。
- VS Code 右下角状态栏检查编码,选 “UTF-8”(不是 “UTF-8 with BOM”)
- Notepad++:菜单栏「编码」→「转为 UTF-8 编码」(不要选带 BOM 的)
- Linux/macOS 验证:
file -i your-page.html应显示charset=utf-8 - Python 生成 HTML 时,
open(..., "w", encoding="utf-8")必须显式指定 encoding
HTTP 响应头中的 Content-Type 会覆盖 meta charset
当 HTML 通过 Web 服务器(如 Nginx、Apache)返回时,响应头里的 Content-Type: text/html; charset=GBK 优先级高于 meta。哪怕你 meta 写得再标准,服务器发错头,页面照样乱码。
立即学习“前端免费学习笔记(深入)”;
- Nginx:在
server或location块中加charset utf-8; - Apache:
.htaccess中写AddDefaultCharset UTF-8(确保没其他地方覆盖它) - 本地双击打开(
file://协议):无 HTTP 头,完全依赖meta,所以位置和文件编码更要严丝合缝 - Chrome DevTools → Network → 点开 HTML 请求 → Headers → Response Headers → 查看
content-type
别用 meta http-equiv="Content-Type" 这种老写法
HTML5 明确推荐 <meta charset="UTF-8">,而 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 是 HTML4 的兼容写法,冗长且在部分场景(如某些构建工具注入逻辑)下容易出问题。
- 它等价于发送 HTTP 头,但语义不清、体积大、易被误删或重复
- 现代编辑器、Linter(如 ESLint + eslint-plugin-html)会直接警告该写法
- 大小写敏感:
UTF8、utf-8、utf8都无效,只有UTF-8是标准值
最容易被忽略的是:BOM(Byte Order Mark)的存在会让 meta charset 在部分环境(尤其是 Node.js 服务端读取、某些 CDN 缓存逻辑)中提前失效——哪怕它物理位置正确,BOM 本身占用了前 3 字节,导致浏览器在 1024 字节内没“干净”地看到 meta 标签。务必确认文件是 “UTF-8 without BOM”。



















