meta charset="UTF-8" 必须是内第一个字符,前面不能有任何内容(含BOM、空格、注释等),否则浏览器仅扫描前1024字节后中断并回退至系统默认编码导致乱码。

直接说结论:meta charset="UTF-8" 必须是 里的第一个字符,前面不能有任何东西——包括 BOM、空格、换行、注释、<script></script>,否则浏览器根本不会认它。
为什么 meta charset="UTF-8" 放错位置就失效
浏览器解析 HTML 时,只扫描前 1024 字节来找 meta charset;一旦遇到以下任一情况,立即中断扫描,fallback 到系统默认编码(Windows 是 GBK,Linux/macOS 通常是 ISO-8859-1):
-
EF BB BF(BOM)出现在文件最开头,实际排第二 -
前有或空行 - 后端模板(如 Thymeleaf、Jinja)在
前注入了动态内容 - 用 Notepad++ 或老旧编辑器误存为 ANSI/GBK
结果就是:源码明明是 UTF-8,页面却显示成 “”“鐢ㄦ埛” 这类典型解码错误字符。
如何验证并清除 BOM 和非法前置内容
先确认问题是否存在,再动手修:
- Linux/macOS 下运行:
xxd -l 4 index.html,若输出含ef bb bf,说明有 BOM;可用sed -i '1s/^\xEF\xBB\xBF//' index.html删除 - PowerShell 中运行:
Get-Content index.html -Encoding Byte | Select -First 3,若输出239 187 191,即 BOM - VS Code 右下角看编码标识 → 点击 → “Reopen with Encoding” → 选
UTF-8→ 再点 “Save with Encoding” → 选UTF-8(**不勾选 “with BOM”**) - Notepad++:菜单栏 “编码” → “转为 UTF-8 无 BOM 编码”
保存后检查:打开文件,把光标移到最开头,按 ← 看是否能左移到 之前——如果能,说明还有不可见字符,得手动删干净。
HTTP 响应头与 meta 的优先级关系
通过 http:// 或 https:// 访问时,HTTP 响应头中的 Content-Type: text/html; charset=utf-8 优先级高于 meta;但 file:// 协议下完全不走响应头,全靠 meta。
- Nginx 配置必须写:
charset utf-8;(小写,结尾分号不能少),放在http、server或location块内 - Apache 的
.htaccess或配置中加:AddDefaultCharset UTF-8(注意大小写) - Express.js 中,
res.send()或res.sendFile()前必须调用:res.set('Content-Type', 'text/html; charset=utf-8') - F12 → Network → 刷新 → 点 HTML 请求 → Headers → Response Headers → 查看
Content-Type是否含charset=utf-8
哪怕 meta 写对了,HTTP 响应头缺失或冲突(比如返回 charset=gbk),照样乱码。两者必须一致,且文件本身也得是 UTF-8 编码。
最容易被忽略的点是:文件真实编码 ≠ 编辑器显示编码 ≠ HTTP 响应头声明 ≠ meta 声明。四个环节只要一个脱节,乱码就必然出现;而 BOM 和前置空白,是本地开发中最常踩的隐形坑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











