必须紧贴开头、任何非ASCII内容(如、注释、BOM、空格)之前,否则浏览器仅扫描前1024字节时会跳过该标签,回退至系统默认编码(Windows为GBK,macOS/Linux为ISO-8859-1),导致乱码或JS报错。

meta charset="UTF-8" 必须写在 开头、任何非 ASCII 内容(包括 <title></title>、注释、<script></script>、空格、BOM)之前,否则大概率失效。
为什么 meta charset="UTF-8" 有时不生效
浏览器解析 HTML 时只扫描前 1024 字节找第一个 meta charset;一旦遇到非 ASCII 字符(比如中文 <title></title>、注释 <!-- ҳ -->、BOM EF BB BF),就会跳过该标签,回退到系统默认编码(Windows 是 GBK,macOS/Linux 是 ISO-8859-1),直接导致乱码或 JS 报 Invalid or unexpected token。
-
<title>ҳ</title> <meta charset="UTF-8">—— 失效:title 中文已超 ASCII 范围 -
<!-- ע --><meta charset="UTF-8">—— 失效:注释含非 ASCII 字符 -
\n<meta charset="UTF-8">—— 可能失效:换行后紧跟非 ASCII 内容,空格/缩进本身不破坏,但若编辑器插入了 BOM 或隐藏控制字符就危险 - 正确写法:
<meta charset="UTF-8"> <title>ҳ</title>——meta紧贴,前面零空格、零注释、零 BOM
HTML 文件本身必须存为 UTF-8(无 BOM)
即使 meta 写对了,如果文件实际保存为 GBK 或 UTF-8 with BOM,浏览器读到的字节流仍是错的。VS Code 默认保存为 UTF-8(no BOM),但打开旧文件时可能自动识别成 GBK —— 这时候改 meta 没用,得先重编码。
- VS Code:右下角点击编码名称(如
GBK或UTF-8 with BOM)→ 选Reopen with Encoding→ 试GBK/UTF-8看哪边中文正常 → 正常后点Save with Encoding→ 选UTF-8(**不是 UTF-8 with BOM**) - Linux/macOS 终端验证:
file -i index.html应输出charset=utf-8;head -c 3 index.html | xxd不应显示ef bb bf - Notepad++:编码 → 转为 UTF-8 编码(**不要选“UTF-8-BOM”**)→ 保存
HTTP 响应头比 meta 优先级更高
如果服务器返回的 Content-Type 响应头里写了 charset=GBK,哪怕 meta 写得再标准,浏览器也强制用 GBK 解析 —— 这是 W3C 规定的优先级:HTTP header > meta charset > 系统默认。
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
立即学习“前端免费学习笔记(深入)”;
- Apache:
.htaccess中加AddDefaultCharset UTF-8,或Header set Content-Type "text/html; charset=UTF-8" - Nginx:
server或location块中加charset utf-8;(注意不是AddDefaultCharset,也不要用add_header Content-Type) - Express:
res.set('Content-Type', 'text/html; charset=UTF-8')必须在res.send()之前调用 - 验证方式:Chrome DevTools → Network → 刷新 → 点 HTML 请求 → Headers → Response Headers → 查
Content-Type是否含charset=utf-8
表单提交和 JS 交互也得同步 UTF-8
光页面显示正常不够,用户输入提交、AJAX 请求、JSON 解析等环节若没对齐 UTF-8,照样出问题:中文 POST 数据变成问号、fetch 返回 JSON 解析失败、CSS content 属性显示方块。
-
<form accept-charset="UTF-8"></form>—— 显式声明表单编码,尤其 Safari 和 Android WebView 对此敏感 - fetch 提交时加 header:
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } - JS 字符串操作、正则匹配中文时,确保源文件是 UTF-8,且没被构建工具(如 Webpack)意外转码
- CSS 中
content: "中文";若显示为空白或方块,大概率是 CSS 文件本身没存为 UTF-8
最易被忽略的是三者不同步:文件存为 UTF-8,meta 写对了,但服务器响应头是 GBK;或者响应头对了,meta 却被注释挡在后面;又或者所有前端都对了,但后端接收 POST 时没设 req.setEncoding('utf8')。验证必须覆盖文件编码、HTTP 响应头、DOM document.characterSet 三处,缺一不可。


















