<meta charset="UTF-8">必须紧随<head>之后、零空格零换行零注释,且文件需保存为UTF-8 with BOM;否则IE6–IE9等老浏览器因仅扫描前1024字节且只识别ASCII,将忽略该标签并fallback至GBK导致乱码或JS语法错误。

meta charset 必须放在 最前面,连注释都不能有
老浏览器(尤其是 IE6–IE9)解析 HTML 时,只扫描前 1024 字节,且只识别 ASCII 范围内的字符。一旦 <meta charset="UTF-8"> 前出现任何非 ASCII 字符(比如中文注释、emoji)、空行、<title> 或 <script>,它就会被跳过,fallback 到系统默认编码(Windows 下通常是 GBK)。
常见失效写法:
-
<head><title>首页</title><meta charset="UTF-8"></head>→<title>不是 ASCII,meta 失效 -
<head><!-- 页面标题 --><meta charset="UTF-8"></head>→ 注释含中文,meta 被忽略 -
<head>\n<meta charset="UTF-8"></head>→ 换行符在部分 IE 中算“非 ASCII 前缀”,导致识别失败
正确写法只有一种:<head><meta charset="UTF-8"> 紧跟 <head>,中间零空格、零换行、零注释。
文件保存必须带 BOM,否则 IE 可能误判为 GBK
IE 在没有 HTTP 头、也没有有效 meta charset 时,会依赖文件头的 BOM(EF BB BF)判断是否为 UTF-8。但 VS Code 默认保存为 “UTF-8”(无 BOM),Notepad++ 默认“ANSI”,这会导致 IE 直接用 GBK 解码 UTF-8 字节流,显示乱码或报错 Uncaught SyntaxError: Invalid or unexpected token(尤其出现在 <script> 开头)。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- VS Code:右下角点击编码名称 → 选
Save with Encoding→UTF-8 with BOM - Notepad++:菜单栏
编码 → 转为 UTF-8-BOM 编码→ 再保存 - 验证方式:用
xxd your.html | head -1(Linux/macOS)或十六进制编辑器查看文件头是否为ef bb bf
HTTP 响应头不能覆盖 meta,但老浏览器根本收不到
现代规范中,HTTP Content-Type 响应头(如 text/html; charset=UTF-8)优先级高于 meta charset。但老浏览器(特别是通过 file:// 协议打开、或本地调试未起服务时)压根不发 HTTP 请求,也就没有响应头——此时全靠 BOM + meta 组合生效。
如果你用的是静态服务器(Nginx/Apache/Express),务必同步配置:
- Nginx:
charset utf-8;放在server或location块内 - Apache:
AddDefaultCharset UTF-8写入.htaccess或主配置 - Express:
res.set('Content-Type', 'text/html; charset=utf-8'),不要只用res.sendFile()
但注意:IE6–IE8 不支持响应头中的 charset=utf-8,仍会退回到 BOM 或 meta;所以 BOM + 正确位置的 meta 是兼容底线。
别用 http-equiv 替代 charset,IE 会忽略
有人试图用 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 兼容旧标准,但这在 IE 中基本无效——该写法属于 HTML4 遗留语法,IE 只认原生 charset 属性。而且它比 charset 多占字节、解析更慢,还容易和真实 HTTP 头冲突。
另外两个高频错误:
-
charset="utf8"或charset="UTF8"→ IANA 注册名只有UTF-8(带短横、大写 U/T/F、数字 8),其他写法在 Safari WebView、某些 Electron 版本中 fallback -
<meta charset="UTF-8">放在<body>里 → 所有浏览器都无视,纯属无效
BOM 和 meta charset 的位置、大小写、拼写,三者缺一不可。少一个,老浏览器就可能当场“失语”。



















