<meta charset="UTF-8"> 是 HTML5 唯一推荐且必须置于 <head> 开头(<title> 之前)的编码声明方式,浏览器在前 1024 字节内扫描该标签以及时启用 UTF-8 解码;其他写法如 http-equiv 版本已被弃用,文件保存编码、HTTP 响应头也须同步为 UTF-8,否则仍会乱码。

<meta charset="UTF-8"> 是 HTML5 中唯一推荐、且必须放在 <head> 开头(<title> 之前)的编码声明方式。其他写法要么过时,要么不可靠,要么直接失效。
为什么只能用 <meta charset="UTF-8">?
浏览器解析 HTML 时,会在前 1024 字节内扫描 <meta charset> 标签;只要它出现在 <title> 和 <script> 之前,就能及时切换到 UTF-8 解码模式。如果写成 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">,虽然在 HTML4/XHTML 中有效,但在 HTML5 中已被明确标记为“不推荐”,部分现代解析器(如 jsdom、某些 WebView)会忽略它。
常见错误现象:
- 页面中中文显示为乱码(如 “æäº›æ–‡æœ¬”)
- emoji 显示为空白方块或问号
- JS 字符串中中文被截断或解析失败
根本原因往往不是标签写错了,而是文件本身没存成 UTF-8 编码 —— 标签只是“告诉浏览器怎么读”,不是“把内容转成 UTF-8”。
立即学习“前端免费学习笔记(深入)”;
文件保存编码必须匹配 charset 值
charset="UTF-8" 不是魔法开关,它要求 HTML 文件实际字节流就是 UTF-8 编码(不含 BOM 更稳妥)。否则标签和文件“说的是一套,存的是另一套”,必然出错。
实操建议:
- VS Code:右下角点击编码名称 → 选 “Save with Encoding” → 选
UTF-8(**不要选 UTF-8 with BOM**) - Notepad++:菜单栏“编码” → “转为 UTF-8 编码”(不是“UTF-8-BOM”)
- Linux/macOS 验证:
file -i your.html应输出charset=utf-8 - Windows PowerShell 验证:
Get-Content your.html -Encoding Byte | Select -First 3结果不应是EF BB BF
特别注意:Word 直接另存为 HTML,默认用 ANSI 或 UTF-16,这种文件即使写了 <meta charset="UTF-8"> 也毫无意义。
HTTP 响应头与 <meta charset> 谁优先?
当页面通过 HTTP 服务访问(如 http://localhost:8080/index.html),服务器返回的 Content-Type 响应头(如 text/html; charset=iso-8859-1)**优先级高于** <meta charset>。此时 meta 标签会被忽略。
验证方法:
- Chrome DevTools → Network → 刷新 → 点击 HTML 请求 → 查看 Response Headers 中的
content-type - Apache 需配
AddDefaultCharset UTF-8;Nginx 需配charset utf-8; - Python
http.server默认不发 charset,所以本地双击file:///才依赖<meta>,而python -m http.server启的服务则完全不认它
charset 的值大小写和拼写有严格要求
必须写成 "UTF-8",不能是 "utf8"、"utf_8"、"Unicode"、"UTF8" 或 "utf-8"。W3C 规范只认可 UTF-8 这一种拼写(全大写 + 连字符)。
容易被忽略的细节:
- 引号必须是英文双引号,
<meta charset=UTF-8>(无引号)是无效 HTML5 语法 - 该标签只能出现一次,且必须在
<head>内;写在<body>里或重复写多次,浏览器可能直接忽略 - 它不支持动态修改:JS 修改
document.head.innerHTML加入该标签,对已开始解析的页面无效
最常被绕过的环节,其实是编辑器保存编码和服务器响应头 —— 标签本身写对了,只是整个链条上某一处脱节,问题就出得毫无征兆。



















