Vue 3偶发字体乱码 - 原因探究

背景:

最近因为项目构建速度过慢,调试速度过慢,把100万行的Vue2项目升级到Vue3 + Vite了,顺手把Element UI升到Plus, Vxe什么都升级了。结果所有其他bug都修完后,测试报来一个神奇的问题, 而且居然是偶发的

预期:

实际结果

分析过程

到测试电脑上点进对应style看看:

js 复制代码
.vxe-table-icon-checkbox-unchecked:before {
    content: "";// 乱码
}

刷新后再打开同个站点却是:

js 复制代码
.vxe-table-icon-checkbox-unchecked::before {
    content: ""; // 正常了
}

回到自己的工位上面, 尝试通过页面GET访问这个css文件,第一次:

js 复制代码
.vxe-table-icon-checkbox-unchecked:before{
    content:"顪�" // 中文乱码,GB2312无疑
}

刷新后:

js 复制代码
.vxe-table-icon-checkbox-unchecked:before {
    content: "";// 乱码
}

再刷新几次就在这两个编码格式之间随机出现。

难道css文件还能不一样的?确认了一下,对应css文件的hash完全一致。都是app.84091779.css,并且如果是不同文件,怎么可能是偶发bug。

从docker里面把对应css文件下载下来,本地CURSOR试着改了改编码测了一下,发现测试的主机上偶发的编码格式是windows1252,刷新后的编码是utf-8。

看了一下对应的CSS文件的Response头

js 复制代码
content-type: text/css

并没有指定charset, 看起来确定是编码问题了。但是这里为什么是偶发的, 基于以前的经验以及AI的回答简单分析下

偶发原因

前提条件

  • 无 Content-Type: charset=
  • 无 @charset 规则
  • 无 BOM
  • 无 HTML 引用文档(直接访问 CSS)

此时浏览器走编码嗅探算法(Encoding Sniffer),而TCP 分包导致嗅探窗口不同,这才是问题的根源 编码嗅探器不会等整个文件下载完,它只扫描首次可用的字节块来做判断。

请求1: 首个 TCP 包包含字节 A~B → 嗅探器认为是 GB2312

请求2: 首个 TCP 包包含字节 A~C(多了一点)→ 嗅探器认为是 Windows-1252

每次请求的 TCP 分包边界不固定(受网络抖动、服务器 buffer 状态影响),导致嗅探器"看到的初始窗口"不同,输出结果不同。


GB2312 和 Windows-1252 为什么特别容易互相误判

这两个编码的字节范围有严重重叠:

字节范围 GB2312 Windows-1252
0x80--0x9F 无效/不用 可打印字符(€ 等)
0xA1--0xFE 汉字双字节 高位拉丁字符

当 CSS 文件包含中文注释或中文内容(哪怕是 UTF-8 编码的,某些字节恰好落在这个范围),嗅探算法的统计模型看到不同长度的样本,可能得出不同结论。

最终方案

nginx css文件头配置里面添加charset=utf-8。

外记

毕竟是AI做的最终分析,还是需要真正去确认是否是浏览器嗅探机制。可以使用wireshark抓一下包

  1. 过滤 tcp && ip.addr == 你的服务器IP
  1. 对比两次请求,看首个数据包(PSH 标志)携带了多少字节
  1. 如果第一帧字节数不同,就能解释为什么嗅探结果不一致
相关推荐
沸点小助手42 分钟前
6月沸点活动获奖名单公示|本周互动话题上新🎊
前端·后端
Csvn1 小时前
React 19 `use()` 来了:以后数据加载可以不用 useEffect?
前端·react.js
没落英雄1 小时前
从零开始搭建一个 AI Agent —— LangChain + TypeScript 实战手记
前端·人工智能·架构
远航_1 小时前
git submodule
前端·后端·github
摸着石头过河的石头1 小时前
从 Webpack 到 RSBuild:前端构建工具的进化之路
前端
疯狂的魔鬼1 小时前
告别 boolean 地狱:一个文件上传组件的状态机实践
前端·设计
竹林8181 小时前
Solana DApp 开发踩坑实录:从零用 @solana/web3.js 实现链上数据查询与交易签名
前端·javascript
狂师1 小时前
测试工程师的AI 技能库:推荐5个让你效率翻倍的Skills
前端·后端·测试
李明卫杭州1 小时前
Vue3 watch 与 watchEffect 深度解析
前端
CodeSheep1 小时前
DeepSeek正式官宣摇人,夯!
前端·后端·程序员