<meta charset="UTF-8">必须置于<head>最开头,因浏览器仅扫描前1024字节查找该标签,错过则fallback至系统默认编码(如Windows的GBK),导致中文、emoji等显示为乱码。

UTF-8 是唯一应使用的字符编码,<meta charset="UTF-8"> 必须出现在 <head> 的最开头,且前面不能有任何字符(包括空格、BOM、注释或 <script>)。
为什么 <meta charset> 必须放在 <head> 最前面?
浏览器只扫描 HTML 文件前 1024 字节来查找 <meta charset>。一旦错过,就会退回到系统默认编码(Windows 是 GBK,Linux/macOS 常是 ISO-8859-1),导致中文、emoji 或带重音的字母显示为乱码(如 )。
常见翻车现场:
-
<script>或<style>写在<meta charset>前 → 浏览器直接忽略该 meta 标签 - 文件以 UTF-8 with BOM 开头,但 BOM 被编辑器错误识别为“不可见字符” → 实际已超出前 1024 字节扫描范围
- 服务端返回的 HTTP
Content-Type头指定charset=GBK→ 会覆盖<meta>,强制用 GBK 解析
如何验证和修复编码配置?
三步确认是否真正生效:
立即学习“前端免费学习笔记(深入)”;
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 用 VS Code 打开 HTML 文件 → 右下角查看编码状态;若显示 “UTF-8 with BOM”,需手动选 “Save with Encoding → UTF-8(no BOM)”
- Chrome DevTools → Network → 点开 HTML 请求 → Headers → 检查 Response Headers 中
Content-Type是否含charset=UTF-8 - 在服务器配置中显式声明:Apache 加
AddDefaultCharset UTF-8;Nginx 加charset utf-8;(注意不是add_header Content-Type)
所有前端资源必须统一用 UTF-8
HTML、CSS、JS、JSON 文件哪怕只有一份是 GBK 编码,就可能引发连锁问题:
- CSS 中
content: "你好"显示为空白或乱码 - JS 里字符串含中文,运行时报
InvalidCharacterError - JSON 语言包加载失败,
fetch().then(r => r.json())抛错,静默 fallback 到空对象
Webpack/Vite 默认读取 UTF-8,但如果源文件是 GBK,构建时不会自动转码——必须提前用 iconv -f GBK -t UTF-8 input.js > output.js 手动转换,或在 VS Code 中关掉 “Auto Guess Encoding”。
表单提交也得管编码
即使页面是 UTF-8,<form> 提交仍可能走旧编码(尤其 Safari 和部分旧 Android 浏览器):
- 加
accept-charset="UTF-8"属性:<form method="post" accept-charset="UTF-8"> - 用
fetch提交时,手动设 header:headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } - 后端接收时,不要依赖客户端声明,统一按 UTF-8 解码请求体
lang 属性和字符编码是两件事,但缺一不可:没 lang,屏幕阅读器读错;没正确 UTF-8,连文字都看不到。


















