必须置于最开头且文件为UTF-8无BOM编码,否则浏览器在前1024字节内无法识别而回退至系统默认编码(如Windows的GBK),导致90%中文乱码;同时需确保HTTP响应头Content-Type、外部JS/CSS文件编码三者均为UTF-8无BOM,缺一不可。

<meta charset="UTF-8"> 必须放在 最开头,且文件本身得是 UTF-8 无 BOM 编码,否则浏览器根本读不到它——这是 90% 中文乱码的根源。
为什么写了 <meta charset="UTF-8"> 还是乱码
浏览器只扫描 HTML 前 1024 字节找这个标签;一旦开头有不可见字符(比如 BOM、空格、注释、<script></script> 或 <link>),就可能跳过它,退回到系统默认编码(Windows 是 GBK,Linux/macOS 是 ISO-8859-1)。
- 用
file -i index.html(macOS/Linux)或 PowerShell 的Get-Content index.html -Encoding Byte | Select -First 3检查开头三字节:出现ef bb bf就是 BOM - VS Code 保存时选 “Save with Encoding → UTF-8”,**不是** “UTF-8 with BOM”
- Sublime/Notepad++ 同样要确认状态栏显示的是 “UTF-8”,不是 “UTF-8-BOM” 或 “UTF-8 with signature”
- 删掉
里<meta charset>前所有内容,包括空行、<!-- -->、<title></title>之前的任何东西
<meta charset> 的写法和位置硬要求
只有这一种写法被 HTML5 标准认可:<meta charset="UTF-8">。其他形式要么无效,要么触发兼容模式。
- ❌
charset=utf8、charset='utf-8'、charset=UTF8—— 不符合规范,部分嵌入式 WebView(如旧版 Android WebView)会忽略 - ❌
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">—— HTML5 已弃用,且易与真实 HTTP 头冲突 - ✅ 必须是
内第一个标签,紧贴开始,前面不能有任何字符(含空格、换行、注释) - ✅ 不要重复写多个
charset,浏览器只认第一个
HTTP 响应头和 meta charset 谁说了算
HTTP 响应头里的 Content-Type: text/html; charset=xxx **永远优先于** <meta charset>。如果两者不一致,浏览器按响应头解析,<meta> 只起 fallback 作用。
立即学习“前端免费学习笔记(深入)”;
- Chrome DevTools → Network → 点开 HTML 请求 → Headers → Response Headers → 查
Content-Type - Nginx 配置需在
http、server或location块中加:charset utf-8;(注意小写,不能写charset=UTF-8) - Apache 需在
.htaccess或httpd.conf中设:AddDefaultCharset UTF-8(大写 UTF-8) - Node.js/Express 中,
res.set('Content-Type', 'text/html; charset=utf-8')必须在res.send()或res.render()之前调用
外部资源(JS/CSS)也得统一 UTF-8
哪怕 HTML 完全正确,只要引入的 .js 或 .css 文件是 GBK 编码,里面含中文字符串(比如 alert("成功"))就会直接报 Uncaught SyntaxError: Invalid or unexpected token。
- 所有
.js、.css、.html文件必须同为 UTF-8 无 BOM - 检查
<script src="app.js"></script>和<link rel="stylesheet" href="style.css">对应文件的编码,方法同 HTML - Webpack/Vite 等构建工具默认处理 UTF-8,但若模板 HTML 本身带 BOM,生成的最终 HTML 仍可能出问题
- 内联
<script></script>和<style></style>里的中文,同样依赖 HTML 文件编码,不是 meta 能覆盖的
真正卡住人的点从来不是“怎么写 meta”,而是三处编码必须同时对齐:HTML 文件保存编码、HTTP 响应头、外部资源文件编码——漏掉任意一个,<meta charset="UTF-8"> 就只是个摆设。



















