眼见不一定为实!记一次JS字符串查找过程中遇到的让人怀疑人生的Bug的修复过程

本文主要是介绍眼见不一定为实!记一次JS字符串查找过程中遇到的让人怀疑人生的Bug的修复过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.浏览器坏了还是我的眼睛出问题了?开始怀疑人生。。。

首先,说一下发生问题的代码的场景,本来我是在写油猴脚本,不懂的可以百度一下,油猴脚本大体的用途就是可以让你在任何网站插入自己的JS代码并执行。

目标网站有一个很长的列表,我在目标网站插入自己的代码,代码的功能是添加一个按钮,按钮点击的时候 根据一个关键词数组在每个列表项里去查询是否包含可能的关键词。有几个列表项内容里包含了以下内容:

于是我想把以上2项内容 归类到一起 我使用了关键词 FCT 去查询所有列表项,结果代码没有查询到。返回一个空数组。着实让我很意外,因为我的代码是可以查询到别的关键词的,所以我没有怀疑是查询代码的问题。我觉得可能是 FCT 这个查询字符串的问题,于是 我重新刷新页面,等全部列表项加载完毕之后,我使用Chrome浏览器自带的查询功能(Ctrl+F)输入 FCT 字符串,更奇怪的事情发生了 ,Chrome也没有查询到相关的关键词。(不信的可以使用浏览器的查找功能看看能不能定位到这个 FCΤ) 我就纳闷了,我明明看见页面有好几个 FCT 为什么 浏览器说没有找到呢???我不解,我困惑。。。

2.根据经验进行初步的Bug分析

这时候,我以往的丰富的踩坑经验告诉我,页面显示的实际内容 可能跟我使用肉眼看到的内容 不一样。。那怎么验证呢??

当你不确定页面显示的字符是什么的时候,或者不知道怎样使用输入法打出那个字符的时候,有一个简单的小技巧,那就是使用复制功能。这个小技巧经常使用在设置一些软件的特殊昵称的时候派上用场,比如你想在自己的昵称里加上 π  或者 ☺  这时候 靠拼音 你是不能打印出这些字符的,这时候 你就可以使用 输入法的特殊符号也行 ,百度相关页面 然后去页面复制这些符号也行。然后就可以粘贴到你需要设置特殊昵称的软件里面了。

言归正传,我使用上面的 FCT 去搜索查询列表项,结果没有找到,那么有一种可能性:页面显示的肉眼看起来像是 FCT 但是实际上可能不是 英文字母的 FCT ,那我们怎么验证呢?

有些朋友应该已经想到了,我们可以使用上面的复制的方法,这时候我打开了Chrome浏览器的开发者工具,然后选中其中一条列表项,在控制台测试了以下代码,先给你们看一下结果,看看有人能看懂不。

对于不熟悉前端的开发者,我先解释一个东西,上面的$0代表我选中的那个HTML元素

我来逐条解释一下 每行代码执行时的环境和意思

1.输出HTML元素包含的文本内容,就是页面看到的内容,这里很清楚的能看到 内容 包含 FCT 

2.我在HTML文本内容里查询 FCT ,这个字符串是我手动输入的,执行结果false表明 没有查询到,虽然上面代码的执行结果里 看着 明明有一个 FCT。。。

3.这个结果就神奇了 ,这个结果是true 标明查询到了,为什么这个看起来和 上面 第二部的 一模一样,执行结果却不一样呢,这个跟第二部手动输入的 FCT 不同的是  这个是我 通过切换到 element面板 使用右键复制出来的内容,并不是手动输入的三个字母,结果就是true了。。。

这时候我拿出了文件比较的神器---Compare

新建2个文本文件:

1.TXT 手动输入 FCT 三个字母
2.TXT 通过element面板复制得到长得像FCT的三个字符

然后进行比对,一比对,果然结果表明两者不一样。。

记事本打开,两个文件看起来都像是 FCT 但是在Compare里 却变成了上图。

虽然不清楚为什么 T 变成了 韦  ,但是至少说明两个文件的内容 是不一样的。

这里基本上可以断定 页面显示的内容 和 我手动 输入的 FCT 三个字母是 不一样的。

肉眼看起来是一样的内容,实际上 是不一样的!

这里,我要插入一个很宝贵的经验:做开发,要使用工具去比较文件是否一样,不要肉眼比较!

3.深入分析和定位出现Bug的原因

上面我们已经知道,页面的显示内容肉眼看起来像是 英文字母 FCT,但是实际上不是,下一步我们就要断定,到底问题出在哪个字母上面,或者页面显示的内容到底是什么??

这时候我又拿出来了控制台 然后测试代码  具体请看以下截图:

由上面的截图的执行结果可以看到,在页面内容里能查询到F、FC,但是查不到FCT,由此可以断定 问题出在 字母  T 上面,现在还不知道这个长得像T的字母到底是什么。

真的万万没想到,万万没想到啊,一大群英文字母里混入了一个长得像英文字母,但是实际上不是英文字母的字符。。。

这时候,我们百度 “像T的字母”,搜索结果前几项就能看到一个 希腊字母里 有一个像 T的字母,

还能看到怎样输出这个字符:点输入法栏--菜单--软键盘--希腊字母

这时候我还是在控制台测试代码 先写上FC然后使用上面的方法输入这个T 然后发现果然查询结果是true 标明 这个字符就是希腊字符。。。我们上面不是说 Chrome浏览器自带的查找 也没找到吗,现在还是使用同样的方法去Chrome的查找框里输入,发现 FCT内容也能查询到了。。。

至此此次神奇Bug的分析已经完成。

4.解决Bug之后的问题思考和扩展

后来过了几分钟,我脑子中突然闪现,这个可以当成一道装逼的面试题啊,请看下面的表达式执行结果,问:为什么是false。

后来,想了想,还是不够迷惑人,只有一个字符 容易被识破,得加一些干扰字符,于是就是优化改造得到了下面的表达式:

这个表达式 能够唬住很多人吧,哈哈。原因有2个:

1.比较的字母是多个,增加找出出问题的那个字母的难度
2.JS里有 true,而此处是 True 多多少少会给回答问题的人增加一些分析问题时候的干扰

哈哈,觉得今天的这个Bug,挺有意思的,所以在此记录一下。也希望能给以后遇到类似问题的兄弟们一点提示和帮助吧。

 

最后,再说一遍:做开发,比较内容一定要使用工具!不要肉眼比较!!!

 

这篇关于眼见不一定为实!记一次JS字符串查找过程中遇到的让人怀疑人生的Bug的修复过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/387235

相关文章

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

MySQL中的InnoDB单表访问过程

《MySQL中的InnoDB单表访问过程》:本文主要介绍MySQL中的InnoDB单表访问过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】