Chrome 特殊字符乱码
—— 一个特殊字符乱码引发的故事
这个是 Vue3 源码里的 example todomvc 在 Chrome 98 里打开的样子
解决过程
- 一开始以为是 encoding 编码问题,使用插件修改编码后发现不管用
- 尝试在 Firefox 打开,正常
- 查看源码,发现是一个特殊字符 ❯ (U+276f)
- Google 关键词 “chrome u+276f”发现跟字体有关
- 修改 css font 为 ‘Segoe UI Symbol’,不生效
- 发现 css 在一个叫 todomvc-app-css 的包里
- todomvc 是一个帮你做技术选型的项目
- 在 online 版的 todomvc demo 里符号显示正常
- 对比两个 demo,尝试给 html 加上
<meta charset="utf-8">
,解决
1 | .toggle-all + label:before { |
问题
如何查看 DOM 元素实际渲染的字体?
Chrome:
Firefox:
如何查看、修改页面的编码格式?
查看
Document.characterSet - Web APIs | MDN
修改
最新版本的 Chrome 和 Firefox 都不支持修改编码,通常字符编码应该在文档或者 HTTP 头中指定,当没有指定编码时,浏览器会根据文档内容自动选择编码
browser - How do I change the character encoding for a webpage in Chrome? - Super User
Text Encoding no longer available in the Firefox menu panel | Firefox Help
当未指定字符编码时 Firefox 的错误提示:
一些测试
- Chrome 会 auto-detect 字符集,当 HTML 中有 ❯ 符号解析为 UTF-8,没有时解析为 windows-1252
- 当 HTML 不包含特殊符号,css 里包含特殊符号时,就出现乱码
- css 里加上
@charset "utf-8"
后正常
- live server 下打开正常,因为 server 自动加上了响应头
Content-Type: text/html; charset=UTF-8
- 解析错误得到的字符是:
â¯
,而如果是字体没有该字符,则会渲染成方块
总结
虽然字符编码的问题遇到过很多,但是缺乏系统性的理解,处于以为明白其实不明白的状态。
乱码原因
源码中的 HTML、CSS、JS 都是以 UTF-8
编码,但是因为没有在文件中指定编码( HTML 中的 meta 标签、CSS 中的 @charset ),而且又是以file://
文件协议访问,响应头里也没有指定编码,此时浏览器会根据 HTML 文档的内容去自动匹配合适的解码方式。因为此案例中特殊字符刚好在 CSS 文件中,HTML 中没有特殊字符,所以浏览器自动识别成了windows-1252
,CSS 中的特殊字符就被解析成乱码。
Charset vs Encoding vs Font
TODO: What’s the difference between encoding and charset? - Stack Overflow
- unicode 是字符集,UTF-8 是编码方式。
- 现在代码一般都是以 UTF-8 编码了,如果解码的时候不以 UTF-8 解码,就会出现乱码。
- 浏览器会根据响应头的
Content-Type
、或者文档中定义的 charset 来解析,如果都不存在,则会自动选择“合适”的编码方式,但是各个浏览器的自动选择行为表现不一致。 - Chrome、Firefox 的新版本都禁用了用户主动选择编码的功能。
参考
❯ - 粗右指尖引号装饰: U+276F - Unicode 字符百科
html - Chrome doesn’t display special character while other browsers do - Stack Overflow
Web fonts don’t show some characters in Chrome for Windows - Stack Overflow
What’s the difference between encoding and charset? - Stack Overflow
Character encodings: Essential concepts