HTML乱码问题根源在于编码声明与实际编码不一致及HTTP响应头优先级更高。需确保编辑器保存为UTF-8无BOM、<meta charset="UTF-8">位于<head>最前且无BOM/空格/注释,并检查服务器是否发送了冲突的Content-Type响应头。
直接改 <meta charset="UTF-8"> 或编辑器保存编码就能解决,不用查半天服务器配置。
编辑器右下角显示的编码(如 “GBK”)必须和 <meta charset> 一致,否则浏览器按声明解码,实际字节却是另一套规则,必然乱码。
UTF-8(不是 UTF-8 with BOM)<meta> 解析file -i index.html(Linux/macOS)或 PowerShell 中 Get-Content index.html -Encoding Byte | Select -First 3,无 BOM 应无 ef bb bf
<meta charset> 必须放在 <head> 最前面浏览器只扫描前 1024 字节找 <meta charset>,如果开头有空格、注释、BOM 或其他字符,这个标签就失效,退回到系统默认编码(如 ISO-8859-1 或 GBK)。
<meta charset="UTF-8"> 是 <head> 内第一个有效标签<head> 前所有空格、换行、<!-- 注释、BOM 字节<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">,HTML5 只认 <meta charset>
<meta> 前塞一堆不可见字符或注释Content-Type 优先级高于 <meta>
只要服务器返回了带 charset 的 Content-Type 头,比如 text/html; charset=gbk,浏览器就完全忽略 HTML 里的 <meta charset>,直接按响应头解码。
立即学习“前端免费学习笔记(深入)”;
file:// 协议):只看 <meta> 和文件实际编码python -m http.server 或 Live Server 插件:默认不发 charset 头,<meta> 生效charset gbk; 这类硬编码指令,应改为 charset utf-8;
res.set('Content-Type', 'text/html; charset=utf-8') 必须在 res.send() 前调用Content-Type
PHP 的 header() 和 Node.js 的 res.set() 如果没显式设置 charset,很多环境会默认发 text/html; charset=iso-8859-1,哪怕你写了 <meta charset="UTF-8"> 也没用。
header('Content-Type: text/html; charset=utf-8');,且不能有 BOM(否则 header() 报错)res.set('Content-Type', 'text/html; charset=utf-8'),别依赖 res.sendFile() 的默认行为<meta> 不影响响应头,得在 PHP 层统一控制default_charset 配置,设为空或 utf-8,避免覆盖手动 headerBOM 是最隐蔽的坑:它藏在文件开头看不见,却能让 <meta charset> 完全失效;而 HTTP 响应头一旦存在,就彻底接管解码权——这两点最容易被忽略,也最难排查。