必须置于最开头,因浏览器仅扫描前1024字节查找该标签,若前面存在注释、bom、空格或等,将导致解析失败而回退至系统默认编码(如gbk或iso-8859-1),引发中文、emoji及js语法乱码。

直接写 <meta charset="UTF-8">,放在 里最开头,且确保文件本身是 UTF-8 编码(不含 BOM),就基本不会乱码。
为什么 <meta charset="UTF-8"> 必须放 最前面
浏览器解析 HTML 时,会在前 1024 字节内查找 <meta charset>;如果前面有注释、<script></script>、空格或 BOM(EF BB BF),它可能被跳过或失效。
-
<!-- 注释 --><meta charset="UTF-8">→ 注释占位,部分旧 WebView 可能忽略 -
<title>首页</title> <meta charset="UTF-8">→<title></title>已超前位置,Chrome/Firefox 通常仍可 fallback 识别,但不保险 - 正确写法:
<meta charset="UTF-8"> <title>首页</title>,且<meta>前不能有任何字符(包括空格、换行、BOM)
怎么确认 HTML 文件真是 UTF-8(无 BOM)
VS Code 默认保存为 UTF-8,但常误选 “UTF-8 with BOM” —— 这会导致微信公众号、某些 Node.js 模板引擎、Webpack/Vite 构建时出错(如 Invalid character 或 header 发送失败)。
- 保存时:在 VS Code 右下角点击编码名 → 选
Save with Encoding→ 严格选UTF-8(不是UTF-8 with BOM) - 验证命令:
xxd -l 3 index.html,输出不含ef bb bf才算干净 UTF-8 - Notepad++:编码 → 转为 UTF-8(无 BOM)→ 保存;Sublime Text 同理,避免 “UTF-8 (with signature)”
HTTP 响应头 Content-Type 和 <meta> 谁说了算
HTTP 响应头的 Content-Type: text/html; charset=utf-8 优先级高于 <meta charset>。本地双击打开 file:// 时没有响应头,才完全依赖 <meta>;而 localhost 或线上环境,两者必须一致,否则浏览器按响应头执行,<meta> 被无视。
- Express 中要显式设置:
res.set('Content-Type', 'text/html; charset=utf-8'),不能只靠res.sendFile() - Apache:
.htaccess加AddDefaultCharset UTF-8;Nginx:charset utf-8;在server或location块中 - GitHub Pages / Vercel 默认发 UTF-8 响应头,但若你上传了带 BOM 的文件,它们会把 BOM 当作内容开头,导致解析异常
常见乱码现象和对应检查点
中文显示成方块、问号、小方框或一堆乱码符号,不是单一原因,需逐层排查:
- 页面全乱:先看 Network → HTML 请求的 Response Headers →
Content-Type是否含charset=utf-8;再用xxd确认文件无 BOM - 仅表单提交后乱码:检查
<form></form>是否加了accept-charset="UTF-8",后端接收时是否按 UTF-8 解码(如 Node.js 的req.body需body-parser配置encoding: 'utf8') - 仅部分文字乱(如标题正常、正文乱):可能是 CSS 中
font-family缺少中文字体,比如只写了sans-serif,没 fallback 到"Microsoft YaHei"或"SimSun"
真正容易被忽略的是:文件编码、HTTP 响应头、<meta> 三者必须全部对齐,缺一不可;而 BOM 是静默杀手,它不报错,但会让几乎所有环节悄悄失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











