Chrome中JavaScript字符串相等性偶现异常,疑与Web Worker相关
字符串全等判断异常:
'center' !== 'center'的罕见Chrome用户问题 问题现象
- 仅极少数Chrome用户(每日数人)触发该异常,首次报错发生在2023年10月16日,用户通常遇到一两次后问题自行消失
- 从报错信息可见,
start是值为"center"的字符串,字符编码与字面量"center"完全一致,但start === 'center'判断结果为假,导致未进入对应分支而触发错误
核心控制代码
function createBaseGradient(gradient) { const start = gradient.start; // ... if (start === 'center') { // ... return '...' } // ... if (start === 'left') { // ... } else if (start === 'top') { // ... } else if (start === 'bottom') { // ... } else if (start === 'right') { // ... } else { internalError( `Illegal gradient start (${JSON.stringify(start)}, ${encodeURIComponent( start )}, ${stringToCharCodes( start )}) of type ${typeof start}. Webworker: ${isWebWorker}. Valid gradient starts are: (${VALID_STARTS}, ${VALID_STARTS.map( stringToCharCodes )})` ); } // ... return '...'; }
捕获到的报错信息
Error: Illegal gradient start ("center", center, 99,101,110,116,101,114,END) of type string. Webworker: false. Valid gradient starts are: (center,left-top,left,left-bottom,top,bottom,right-top,right,right-bottom, 99,101,110,116,101,114,END,108,101,102,116,45,116,111,112,END,108,101,102,116,END,108,101,102,116,45,98,111,116,116,111,109,END,116,111,112,END,98,111,116,116,111,109,END,114,105,103,104,116,45,116,111,112,END,114,105,103,104,116,END,114,105,103,104,116,45,98,111,116,116,111,109,END)
背景细节
- 参数
gradient由Web Worker创建,gradient.start是从Brython字符串类型转换而来的JavaScript字符串 - 该错误不仅在
start为"center"时触发,也会在start为其他有效值时出现
已尝试的排查措施
- 添加详细日志,记录字符串的JSON序列化结果、URI编码、字符编码、类型等信息
- 将函数中所有用于判断的字符串存入常量并构建
VALID_STARTS数组,排除浏览器扩展篡改的可能性 - 添加日志验证是否进入
start === 'center'分支后未返回,该日志从未触发 - 构造Web Worker字符串传递的最小复现示例(如传递
'abc'后判断全等),运行数百万次未复现错误 - 排查Chrome新版本发布记录、我方部署记录,未发现与报错时间的关联;浏览Chrome公开Bug库未找到相关线索
新增排查日志与进展
在if (start == 'center')判断前添加以下日志,得到结果如下:
const a = start + '!'; // center! const b = CENTER + '!!'; // center!! const f = start == CENTER; // false const c = start === CENTER; // false const d = typeof start; // string const e = start.toString() === CENTER.toString(); // true const g = start.normalize('NFC') === CENTER.normalize('NFC'); // true
- 调用
.toString()或对字符串进行NFC归一化后,全等判断结果变为真,但此前字符编码对比已显示一致,目前无法理解该现象的原因
疑问
- 为何
typeof start为'string',但实际可能并非标准字符串? - 是否存在意外修改String原型导致相等性判断异常的可能?
内容的提问来源于stack exchange,提问作者Austin Schick
相关产品推荐
相关产品推荐

