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. 如果第一帧字节数不同,就能解释为什么嗅探结果不一致
相关推荐
英俊潇洒美少年1 小时前
Vue2/Vue3 vue-i18n完整改造流程(异步懒加载+后端接口请求)
前端·javascript·vue.js
空中海7 小时前
第七章:vue工程化与构建工具
前端·javascript·vue.js
zhensherlock8 小时前
Protocol Launcher 系列:Trello 看板管理的协议自动化
前端·javascript·typescript·node.js·自动化·github·js
zhuà!8 小时前
element的el-form提交校验没反应问题
前端·elementui
龙猫里的小梅啊8 小时前
CSS(一)CSS基础语法与样式引入
前端·css
小码哥_常8 小时前
从0到1,开启Android音视频开发之旅
前端
渔舟小调8 小时前
P19 | 前端加密通信层 pikachuNetwork.js 完整实现
开发语言·前端·javascript
qq_12084093718 小时前
Three.js 工程向:Draw Call 预算治理与渲染批处理实践
前端·javascript
旷世奇才李先生10 小时前
Vue3\+Vite\+Pinia实战:企业级后台管理系统完整实现(附源码)
vue.js
不会聊天真君64711 小时前
JavaScript基础语法(Web前端开发笔记第三期)
前端·javascript·笔记