必须位于内首个非空白节点,否则浏览器扫描前1024字节时可能被bom、注释、空格或不可见字符干扰而失效;若文件实际编码与声明不一致(如声明utf-8但文件存为gbk),或http响应头content-type指定其他charset,均会导致乱码。

meta charset 声明必须存在且位置正确,否则浏览器会 fallback 到系统默认编码(Windows 是 GBK),中文必然乱码。
为什么 meta charset="UTF-8" 放在 开头也失效?
浏览器只扫描 HTML 前 1024 字节找 charset 声明。一旦开头有 BOM、注释、空格或不可见 Unicode 字符(比如全角空格 U+3000),就可能跳过或误判 <meta> 标签。
- 用
xxd -l 4 index.html检查开头是否为ef bb bf(BOM);是则需保存为纯 UTF-8(不含 BOM) - VS Code 状态栏显示 “UTF-8 with BOM” 时,点它 → “Save with Encoding” → 选 “UTF-8”(不带 BOM)
- 删掉
前所有内容:包括 HTML 注释<!-- -->、空行、全角空格、<script></script>或<link>标签 - 确保
<meta charset="UTF-8">是内第一个非空白节点
HTTP 响应头 Content-Type 和 meta 冲突怎么办?
当通过 http:// 或 https:// 访问时,服务器返回的 HTTP 响应头中 Content-Type 优先级高于 meta。若头里写的是 charset=gbk,哪怕 meta 写对了也白搭。
- F12 → Network → 刷新 → 点 HTML 请求 → Headers → Response Headers → 查看
Content-Type值 - Nginx 配置要加
charset utf-8;(在server或location块内) - Apache 要在
.htaccess加AddDefaultCharset UTF-8 - Node.js/Express 中,
res.set("Content-Type", "text/html; charset=utf-8")必须在res.send()之前调用
本地双击打开 index.html 乱码,但服务器上正常?
这是 file:// 协议的典型问题:没有 HTTP 响应头,浏览器完全依赖 meta 和文件自身编码。只要文件实际不是 UTF-8,或开头有干扰,就会失败。
- 用
file -i index.html(Linux/macOS)或Get-Content index.html -Encoding Byte | Select -First 3(PowerShell)确认真实编码 - VS Code 中右下角编码显示不是 “UTF-8”,就点它 → “Reopen with Encoding” → 试 GBK / UTF-8 → 找到能正常显示的编码 → 再 “Save with Encoding” → 选 “UTF-8”
- 绝对不要用记事本保存 HTML:它默认存为 ANSI(Windows-1252)或 GBK,且不提示
- Sublime Text / Notepad++ 保存时明确选 “UTF-8”,禁用 “UTF-8 with BOM”
最常被忽略的一点:文件本身编码和 meta 声明必须严格一致。声明是 UTF-8,文件却用 GBK 存,浏览器照解 UTF-8 字节流,出来的就是一堆 ÃÂ。改声明不如改保存方式——因为编辑器不会帮你把 GBK 字节转成 UTF-8 字节,它只会原样写入。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











