必须将置于最前端,紧贴起始标签后,前面不能有bom、注释、空格或任何其他字符;否则浏览器在扫描前1024字节时无法识别,将回退至系统默认编码(如windows的gbk)导致标题栏及早期内容乱码。

必须放在 开头,紧贴 起始标签之后,前面不能有任何字符(包括空格、换行、注释、BOM)。 其他位置几乎都失效 —— 浏览器只扫描 HTML 前 1024 字节找它,一旦错过就 fallback 到系统默认编码(Windows 是 GBK,Linux/macOS 多为 ISO-8859-1),中文立刻乱码。
为什么 <meta charset="UTF-8"> 放在 <title></title> 后面会失效
浏览器解析 HTML 时,<title></title> 内容会立即被读取并用于渲染标签页标题、SEO 提取等,此时还没看到 <meta charset>,只能用默认编码(如 ISO-8859-1)解码 —— 中文、emoji、全角标点全变成 或乱码。Chrome/Firefox/Safari 均如此,Android WebView 更敏感。
- 实际现象:
<title>你好</title> <meta charset="UTF-8">→ 标签页显示 “好” 或空白 - DevTools 控制台可能报错:
Uncaught SyntaxError: Invalid or unexpected token(JS 中含中文字符串时) - 即使后续
<meta charset>存在,也无法修正已错误解析的<title></title>和早期文本节点
哪些“看不见”的东西会挡住 <meta charset>
它们都在 开头但早于 <meta charset>,导致浏览器跳过该标签:
- BOM 字节(
ef bb bf):VS Code 默认“UTF-8 with BOM”保存时自动添加,占前 3 字节,破坏扫描定位 - HTML 注释:
<!-- 说明 -->,哪怕只有一行,也会让浏览器跳过后续匹配 - 空白字符:开头的空格、制表符、换行符(
\n、\r) - 其他标签:
<script></script>、<link>、<base>等任何非<meta charset>的标签
验证方法:head -c 4 yourfile.html | xxd 查 BOM;VS Code 右下角编码状态栏看是否显示 “UTF-8 with BOM”;F12 → Network → Headers 查 Response Headers 中 Content-Type 是否含 charset=utf-8。
HTTP 响应头和 <meta charset> 谁说了算
HTTP 响应头中的 Content-Type: text/html; charset=utf-8 优先级高于 <meta charset>。但 file:// 协议下无响应头,<meta charset> 是唯一依据 —— 所以本地测试必须严格校验其位置与文件编码。
- Nginx 配置:
charset utf-8;(小写,不加引号,不写 BOM) - Apache:
AddDefaultCharset UTF-8 - Express:
res.set('Content-Type', 'text/html; charset=utf-8')必须在res.send()之前调用 - 若响应头是
charset=gbk,哪怕写了<meta charset="UTF-8">,页面仍按 GBK 解析 —— 乱码不可避免
真正可靠的组合:响应头明确声明 + 文件存为 UTF-8 without BOM + <meta charset="UTF-8"> 紧贴 开头 —— 少一个环节,中文就可能出问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











