必须置于最顶部(紧接后、前),因浏览器流式解析遇非ASCII字符时若未读到该声明,会按fallback编码(如ISO-8859-1)错误解码且不可逆,导致中文乱码或JS执行中断。

meta charset 必须放在 的最顶部,且紧接在 标签之后(或 <title></title> 之前),否则浏览器可能已按默认编码(如 ISO-8859-1)开始解析,导致中文等非 ASCII 字符显示为乱码。
为什么 meta charset="UTF-8" 要放最前面?
浏览器解析 HTML 是流式进行的。一旦遇到非 ASCII 字符(比如中文、emoji),而此时还没读到 meta charset 声明,就会用 fallback 编码(通常是系统默认或历史遗留编码)解码——这个过程不可逆,后续再声明 UTF-8 也救不回已错解的字节。
- 实测:把
<meta charset="UTF-8">放在<title></title>后面,页面中<title>你好</title>很可能显示成 “ä½ å¥½” - 即使整个文件保存为 UTF-8 无 BOM,也不代表浏览器会自动识别;它只看 HTML 内部的显式声明位置
- HTML5 规范明确要求:该标签应是
中第一个子元素(除注释和空格外)
charset 声明写法与常见错误
只有一种推荐写法:<meta charset="UTF-8">。它简洁、无歧义、被所有现代浏览器支持。
- ❌ 错误:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">—— 这是 HTML4/XHTML 风格,冗长且易因空格/大小写出错 - ❌ 错误:
<meta charset="utf-8">—— 属性值没加双引号,不符合强制规范,部分解析器会忽略 - ❌ 错误:
<meta charset="utf8">—— UTF-8 必须带短横线,写成utf8不被识别(Chrome 会 fallback 到 ISO-8859-1) - ✅ 正确:
<meta charset="UTF-8">—— 全大写UTF-8,双引号包裹,无空格,独占一行
模板文件本身编码也要匹配 charset 声明
声明是“告诉浏览器怎么解”,文件保存是“实际存了什么字节”。两者不一致,照样乱码。
立即学习“前端免费学习笔记(深入)”;
- 编辑器必须将 HTML 文件保存为 UTF-8 编码(无 BOM 更稳妥,尤其对旧版 IE)
- 用 VS Code 打开时右下角查看编码,点击可切换;Sublime Text 用 “File → Save with Encoding → UTF-8”
- Node.js 模板引擎(如 EJS、Pug)默认按 UTF-8 渲染,但若读取的 .ejs 文件本身是 GBK 编码,
res.render()输出仍会错 - Python 的 Jinja2 若加载模板时未指定
encoding='utf-8',也可能读错字节
最容易被忽略的是:服务器响应头里的 Content-Type 与 HTML 内 meta charset 冲突时,浏览器以响应头为准——所以本地开发用 file:// 协议时,完全依赖 meta;而部署后务必检查 HTTP 响应头是否含 charset=utf-8,否则前端声明无效。



















