如何在浏览器上优雅的进行调试 您所在的位置:网站首页 浏览器控制台指令 如何在浏览器上优雅的进行调试

如何在浏览器上优雅的进行调试

2023-03-12 16:11| 来源: 网络整理| 查看: 265

日常开发我们碰到的很多问题,通常我们都会通过console或debugger 去快速定位排查问题,会定位问题可以节省很多时间。也就是我经常说的工欲善其事,必先利其器。所以在这和大家发现几个容易让大家忽略的调试技巧;

控制台打印

在平常的开发中我们应该常常用到下面这些命令去进行调试

console.log(‘Hello World!’); // 最最常用 console.info(‘Something happened…’); // 用于打印提示性信息 console.warn(‘Something warn happened…’); // 用于打印警示信息 console.error(‘Something error happened…’); // 用于打印错误信息

但是仅此而已?下面👇展示几个你不知道或者你常常会忽略的技巧

1、console.trace()

如果你想知道消息是哪里打印出来的,使用console.trace()来获取要打印的数据的stacktrace;

2、console.time() && console.timeEnd()

如果你想分析函数的性能,可以使用console.time()来计时,console.timeEnd()来结束计时,控制台会打印出两次之间的时间差;

注:两个方式需要传入一个字段名,以此来区分多个计时器,当你同一个方法在执行期间多次传人则只有第一个会生效;

3、console.count

如果你想记录一下一个函数被调用了多数次的话可以使用这个方法;

4、console.assert

如果你想某些为假的条件下输出消息,而不是用if-else时可以使用这个方法;

注:nodejs下不支持这种写法,会报错;

5、console.group() & console.groupEnd()

如果你想把所有的console.log全部聚合在一起的话可以使用这个方法;

6、console.dir()

打印出该对象的所有属性和属性值,console.dir和console.log的区别并不明显,唯一的区别就是在dom节点的打印方面,log直接展示对应的元素,而dir是以对象的形式把属性和值进行呈现

demo

let timeDemo = async () => { console.time(); setTimeout(() => { console.log('3000 timeout') console.timeEnd(); }, 3000) } let traceDemo = () => { console.trace('trace') }; let assertDemo = (mahkSex) => { let isTrue = mahkSex === 'box'; console.assert(isTrue, 'mahk is a box'); }; let groupDemo = () => { console.group() console.log('i in groud 1'); console.log('i in groud 2'); console.log('i in groud 3'); console.groupEnd(); } let demo = (type) => { if (type === 'trace') { traceDemo(); } if (type === 'time') { timeDemo(); } if (type === 'assert') { assertDemo('girl'); assertDemo('box'); } if (type === 'group') { groupDemo(); } console.count('dome这个方法被调用的次数:'); }; demo('trace') // demo('time') // demo('assert') // demo('group') // let test = { a: 1 }; // console.log(test.a); // console.log(test); // test.a++; // console.log("%c这是一段被修改样式的输出文字", "color: blue; font-size: x-large; background: #ddd");

PS:console.log 打印的值不准确问题

有些时候在使用·console.log() 打印对象的时候,打印出来的值不符合预期。这是为什么呢?

let test = { a: 1 }; console.log(test.a); console.log(test); test.a++;

有一种说法是:console.log() 是一个异步的方法,浏览器在处理的时候对于这种读取 i/o 的操作一般会放到比较靠后的位置去处理。所以有些时候打印出来的值不符合预期。

还有一种说法是,当在打印一个对象的时候,由于对象中的值是引用的内存中的值,所以就会存在当打印对象的时候,当引用到对象中的值的时候,对象中的值已经发生变化了。所以才会存在打印结果与预期不一致的情况。

在《你不知道的javascript中卷》第二部分异步和性能1.1节异步控制台部分有提及:

并没有什么规范或一组需求指定console.* 方法族如何工作——它们并不是JavaScript 正式的一部分,而是由宿主环境(请参考本书的“类型和语法”部分)添加到JavaScript 中的。因此,不同的浏览器和JavaScript 环境可以按照自己的意愿来实现,有时候这会引起混淆。 尤其要提出的是,在某些条件下,某些浏览器的console.log(..) 并不会把传入的内容立即输出。出现这种情况的主要原因是,在许多程序(不只是JavaScript)中,I/O 是非常低速的阻塞部分。所以,(从页面/UI 的角度来说)浏览器在后台异步处理控制台I/O 能够提高性能,这时用户甚至可能根本意识不到其发生。

console.log打印出来的内容不一定正确。一般对于普通类型number、string、boolean、null、undefined的输出是可信的。但对于Object等引用类型来说,则就会出现上述异常打印输出。

所以对于一般基本类型的调试,调试时使用console.log来输出内容时,不会存在坑。但调试对象时,要么你就把对象深拷贝一下,要么你就debugger,最好还是使用断点(debugger)这样的方式来调试更好。

debugger断点调试

了解source面板

断点类型

1、行断点:代码运行到当前行之前暂停执行(常用)

在源代码添加debugger关键字

或者点击Sources面板中的源代码的行号

2、条件行断点:当满足条件时才会触发该断点

右击Sources面板中的源代码的行号,选择“Add conditional breakpoint”

3、dom节点断点

当我们进行ui问题排查时,例如ui为啥属性突然发生变更时,就可以使用这个方法,切换到Elements页签,在想要添加断点的DOM节点上右键点击,在最下边的Break on菜单项可以找到这三个选项. 当我们的脚本触发了DOM的修改时,devtools会直接跳转到Source页签并定位到修改DOM的那行代码上

subtree modifications 子节点内容的的修改删除新增(子节点的属性修改不会触发,当前节点的修改不会触发)attribute modifications 当前节点的属性修改删除新增node removal 当前节点被移除

4、异常事件断点

当我们不知道哪里会代码异常时开启异常事件断点,能帮助我们自动定位到异常问题,及时修复

4、XHR/Fetch 断点(感觉不是很实用)

在页面发出XHR或Fetch请求前加断点

5、Event Listener 事件监听断点

可以在所有类型的事件函数被出发前加断点

6、Function 函数断点

把想调试的函数名作为参数,调用debug()函数,可以在每次执行该函数前暂停执行代码

参考文档 --> 浏览器原理与使用上 - 使用篇: - 知乎

demo

let demoObject_1 = { a: 1, b: 'test', } let demoObject_2 = { a: 1, b: 'test', } const demoFunction_1 = () => { let a = 2; console.log(demoObject_1); demoObject_1.a++; demoObject_1.a++; demoObject_1.a++; console.log(demoObject_1); demoObject_1.a++; } const demoFunction_2 = () => { let a = 2; console.log(demoObject_2); demoObject_2.a++; console.log(demoObject_2); demoObject_1.a++; } const demo1 = () => { demoFunction_1(); demoFunction_2(); } demo1();

chrome常被忽略的奇技淫巧

1、修改请求参数重新发起

然后复制于控制台然后修改请求参数重新发起接口请求

2、控制台中$的使用

$_:可以返回控制台上次输出对象

$0、$1、$2、$3、$4:$0、$1、$2、$3 和 $4 命令用作在 Elements 面板中检查的最后五个 DOM 元素或在 >Profiles 面板中选择的最后五个 JavaScript 堆对象的历史参考。$0 返回最近一次选择的元素>或 JavaScript 对象,$1 返回仅在最近一次之前选择的元素或对象,依此类推。

$(selector) :返回带有指定的 CSS 选择器的第一个 DOM 元素的引用,此函数等同于调用document.querySelector() 函数。

$$(selector) :返回与给定 CSS 选择器匹配的元素数组。此命令等同于调用document.querySelectorAll()。

3、使用css样式可以用来更改控制台的输出样式

CSS 格式说明符%c可以修改在控制台中输出的样式。以你要修饰的文字配上占位符开始,然后在第二个参数中写上你要展示的风格

console.log("%c这是一段被修改样式的输出文字", "color: blue; font-size: x-large; background: #ddd");

4、Filter过滤

排除过滤(反向搜索)

在要搜索的字符前加-,表示反向搜索

多条件搜索

每个搜索间用 空格斜杆空格隔开 / 

支持正则搜索,直接输入正则即可

5、直接在控制台导入cdn资源包

GitHub - pd4d10/console-importer: Easily import JS and CSS resources from Chrome console.

通过引入这个插件即可按需在控制台引入cdnjs

例如 我绝的这个moment-js这边包的方法挺好的,想要引用,就可以进行如下操作

6、通过浏览器配置,解决跨域问题(修改浏览器属性解决浏览器安全策略拦截问题)

在Google启动文件属性中增加目标项中增加--disable-web-security --user-data-dir,重新打开浏览器即可临时本地浏览器跨域问题

重点安利 -- spy-debugger - 移动端抓包调试工具

什么是spy-debugger

spy-debugger 是一个一站式页面调试、抓包工具。远程调试任何手机浏览器页面,任何手机移动端webview(如:微信,HybridApp等)

特性:

页面调试+抓包操作简单,无需USB连接设备支持HTTPS。spy-debugger内部集成了weinre、node-mitmproxy、AnyProxy。自动忽略原生App发起的https请求,只拦截webview发起的https请求。对使用了SSL pinning技术的原生App不造成任何影响。可以配合其它代理工具一起使用(默认使用AnyProxy) (设置外部代理)

使用教程

1、安装spy-debugger

npm install -g spy-debugger

2、通过spy-debugger相关命令运行插件

相关命令如下

spy-debugger 按默认配置启动spy-debugger -p 8888 设置端口号为8888,默认是 9888spy-debugger -e http://127.0.0.1:8888 设置外部代理,默认使用 anyproxyspy-debugger -i true 是否允许weinre监控iframe加载的页面,默认是 falsespy-debugger -w true设置页面内容为可编辑模式,默认是 falsespy-debugger -b false是否只拦截浏览器发起的https请求,默认是 true

有些浏览器发出的connect请求没有正确的携带userAgent,这个判断有时候会出错,如UC浏览器。这个时候需要设置为false。大多数情况建议启用默认配置:true,由于目前大量App应用自身(非WebView)发出的请求会使用到SSL pinning技术,自定义的证书将不能通过app的证书校验。

spy-debugger -c true是否允许HTTP缓存 ,默认是 false

3、手机与电脑在同一个局域网下开启,手机开启网络代理,例如上图,此时我要在手机配置代理192.168.31.114:9888

4、手机安全证书 -> https://spydebugger.com/cert

注意⚠️:一定开启了手机网络代理之后再去打开这个域名哈,直接打开域名会被重定向到18🈲,别说我没提醒你

完成上述操作即可进行代理了,通过浏览器打开 http://127.0.0.1:50470

参考文档 --> spy-debugger: spy-debugger 是一个一站式页面调试、抓包工具

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有