6

F12-开发者工具常用操作与使用说明之源代码sources

 1 year ago
source link: https://blog.51cto.com/u_15685951/5577027
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

F12-开发者工具常用操作与使用说明之源代码sources

原创

流指斜阳 2022-08-15 11:32:42 ©著作权

文章标签 代码段 作用域 控制台 开发者工具 源代码 文章分类 其它 前端开发 阅读数216

我们先来一个小示例给大家看一下:

F12-开发者工具常用操作与使用说明之源代码sources_源代码

大家能看出来上面的代码为什么输出的是17吗?按照正常的输出应该是7才对呀!如果你对此有疑惑,说明你在平时调试代码的时候已经浪费了很多时间了哦。

今天就带大家来探索一下开发者工具中源代码的使用,这里提供了非常方便并且有用的功能。

大家可以借助它的一些神奇的能力,来解决那些困扰我们的问题,希望你能够掌握并熟练的使用它们,下面就让我们来一起看看它的魅力吧!

F12-开发者工具常用操作与使用说明之源代码sources_控制台_02

源代码面板从视觉效果上分为三个区域:菜单区、内容区、监听区。

F12-开发者工具常用操作与使用说明之源代码sources_源代码_03

其中菜单区有五个子分类:

F12-开发者工具常用操作与使用说明之源代码sources_作用域_04
  1. 网页(Page):指页面源,包含了该页面中所有的文件,即使多个域名下的文件也都会展示出来,包括iframe中的,方便我们对文件进行查看。
  2. 文件系统(Filesystem):可以关联本地的一个文件夹,当在内容区域修改该文件夹中的内容时,会同步修改磁盘中的文件,适合实时修改项目文件,并会直接同步到编辑器中。
  3. 替换(Overrides):可以使用本地中的文件替换当前页面中的文件,适合在调试过程中实时修改代码,但不会保存到磁盘中​​(即不会修改项目源文件,编辑器中内容依然不变)​​。
  4. 内容脚本(Content scripts):用来展示在当前页面中的扩展程序代码,如果有某个扩展程序在当前页面执行过,那么将会展示在这里。
  5. 代码段(Snippets):主要用来执行一些预置脚本代码,这样可以不用每次都编写同样的调试代码,直接执行相应的代码片段即可。

内容区是用来展示各个文件的内容,以便进行打断点等操作,可以对代码进行格式化。

监听区主要是供我们操作和查看断点的执行,以及监听我们设置的事件触发,一般包括了以下10个方面:

F12-开发者工具常用操作与使用说明之源代码sources_作用域_05
  1. 顶部操作区:主要用来控制断点的执行。
  2. 监视(Watch):可以查看当前作用域链上的变量,为实时变化,默认只有this,可以手动添加需要监视的变量,可以写表达式。
  3. 断点(Breakpoints):显示当前断点所在的文件、行数以及该行的内容。单击可快速定位。
  4. 作用域(Scope):主要包括本地(Local)→脚本(Script)→全局(Global)中的所有变量。
  5. 调用堆栈(Call Stack):当前代码的调用者,以及调用者的调用者。
  6. XHR/提取断点(XHR/fetch Breakpoints):用来给请求设置断点,可以拦截所有请求,也可以设置过滤条件。
  7. DOM断点(DOM Breakpoints):如果为dom元素添加了断点,那么在此显示出被打断点的元素。
  8. 全局监听器(Global Listeners):注册的全局事件会在这里显示,如onfocus、onerror等。
  9. 事件监听器断点(Event Listener Breakpoints):如果注册了某些事件,如load、copy等,那么在触发这些事件的时候,会自动在执行该行为的代码处进入断点状态。
  10. CSP违规断点(CSP Violation Breakpoints):表示一种内容安全策略(Content Security Policy的简写),如果启用这个策略,那么浏览器会对一些可能不安全的操作给出限制,在抛出错误提醒的同时,将当前操作直接中断。

下面将对这些内容一一进行详细的讲解,我会通过示例的方式给大家进行演示。

由于内容区与另外两个有关联,是它们操作的基础,因此先介绍一下这块。

大家一看就知道是用来展示内容的,像一些js、html、css等各种各样的文件,包括图片也可以在这里显示,主要是用来查看和调试我们的代码。

可以在想要的位置打上断点,只需要单击该行代码左侧的行号处即可:

F12-开发者工具常用操作与使用说明之源代码sources_代码段_06

先做一个简单的介绍,更详细的内容,我们会在接下来的讲解中穿插说明。

网页(Page)

在这里通过目录结构的方式,清晰的展示出当前页面包含的所有文件,请看下面:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>source源代码</title>
<style>
</style>
</head>

<body>
<iframe src="8.html" frameborder="0"></iframe>
<div id="div" date-key="divKey">我就是我</div>
<input type="text" id="myInput">
<input type="button" value="点我" id="btn">
<script src="9.js"></script>
<script src="https://lf3-short.bytegoofy.com/slardar/fe/sdk-web/plugins/blank-screen.0.3.19.js"></script>
<script>
</script>
</body>

</html>

在浏览器中呈现的效果为:

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_07

我们看下这些文件的层级:

F12-开发者工具常用操作与使用说明之源代码sources_源代码_08

通过清晰的结构,我们能够很容易找出相应的文件,并了解它们之间的关系,点击其中的某个文件,就可以查看它的内容了。

文件系统(Filesystem)

主要是用来跟本地的文件进行关联,可以把这里想象成是一个编辑器,比如vscode,相当于是用vscode打开了一个项目文件夹一样,你可以用这里的文件系统来打开你的某个文件夹,之后你就可以操作里面的文件,做任意的编辑,保存之后就会直接修改磁盘上的文件,就好像是在vscode里面操作一样。

我的项目文件放在code文件夹下面,里面有两个文件,如下图:

F12-开发者工具常用操作与使用说明之源代码sources_作用域_09

我在文件系统添加这个文件夹:​​(选择完毕之后别忘了在页面上的弹出选项中点击允许,下同)​

F12-开发者工具常用操作与使用说明之源代码sources_作用域_10

这个时候我们在这里的内容区修改9.js文件中的name为wang,age为22,return返回m + n + 1。

F12-开发者工具常用操作与使用说明之源代码sources_代码段_11

发现文件出现了小星星标识,这时ctrl + s保存一下,就会看到文件也跟着变更了。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_12

细心的小伙伴可能在上面已经看到9.js文件图标的右下角有一个小圆点,这表示该文件与当前页面有关联,此时这种类型的文件,我们可以直接在网页(Page)里面修改也是可以的。这里不再做演示了。

替换(Overrides)

当我们想在页面上面直接修改代码进行调试的时候,但是又不想保存到本地磁盘上面直接修改本地文件,那么可以使用替换功能,将当前修改的文件副本临时保存到一个我们指定的文件夹中,用这个文件来替换当前页面中的文件,以达到实时调试的效果。

首先我们在刚才的项目路径下面新建一个replace文件夹,用来存放这些临时用来替换的文件。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_13

然后我们把这个replace作为选择放置替换项的文件夹。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_14

现在我们去到网页(page)中修改9.js,把return的m + n + 1改成m + n + 5,按ctrl + s保存之后,会发现replace发生了变化。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_15

同时输出值也发生了实时的改变。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_16

而且本地源文件是没有变化的。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_17

利用这个功能,我们就可以在页面上调试的时候,能够直接修改文件内容,并看到相应的结果,而不会去影响到源文件的代码。

内容脚本(Content scripts)

主要针对扩展程序,比如vue插件等,大家有兴趣的可以去了解一下,因为这里不属于本项目的内容,因此不做过多讲解。

代码段(Snippets)

可以把这个理解成是一个可执行代码的文件在当前作用域中生效,需要注意的是,这块的代码段不但可以在正常情况下执行,也可以在断点调试的时候执行,天然具有当前的作用域上下文。

比如我们想要获取页面中的所有input。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_18

那么首先新建一个代码段,命名为“页面中所有input”,并编写文件的内容。

F12-开发者工具常用操作与使用说明之源代码sources_代码段_19

然后我们在左侧的这个代码段名称上面右键,选择运行,接下来去控制台输出allInput这个变量,看看会出现什么。

F12-开发者工具常用操作与使用说明之源代码sources_控制台_20

很神奇有没有?我们发现当前作用域下,该变量是完全可用的。

接下来我们试着调试一下文章开始的那段代码。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_21

然后我们在页面的return处打上断点,刷新页面重新加载一下。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_22

可以看到m的值为3,n的值为4,这时我们去代码段里面新建一个“修改add返回值”的代码段,让m为10,n为7,保存之后运行一下。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_23

我们把鼠标放上去看看有什么变化?

F12-开发者工具常用操作与使用说明之源代码sources_控制台_24

可以发现,m和n的值已经都被改变了,其实我们再按下F10,断点会原地再走一次,看下效果。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_25

这下是不是更清晰了,现在我们把断点放过去,来看一下控制台的输出。

F12-开发者工具常用操作与使用说明之源代码sources_控制台_26

结果已经受到了影响,跟我们开头的那个结果一模一样,大家现在是不是完全就明白了呢。

这个时候,我们在控制台输出一下m和n,看看会发生什么。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_27

发现这两个变量已经完全不存在了,这是因为当时执行代码段时的上下文已经不存在了,作用域已经被销毁。

因此我们可以利用代码段的这个特性,去做很多好玩的事情。

如果你对此感兴趣,那就让我来继续为你介绍其他的功能。

顶部操作区

这里包含了我们调试的时候的所有操作,对于我们在打断的时候会经常用到。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_28

相信大家对这些按钮已经非常熟悉,这里只做个简单的说明。

  1. 继续执行脚本,也就是放过当前断点,直接进行到下一个断点,快捷键F8
  2. 跳过下一个函数调用,其实就是我们经常说的执行到下一行,或者更准确的说是执行到下一个语句,可以理解为下一个可以添加分号的地方,其中逗号表达式或者三目运算符等即使跨越多行,也是作为一个语句来跳过的,也叫步进,快捷键为F10
  3. 进入下一个函数调用,就是说会进入执行函数的方法内部,即使该函数中没有打断点,也会自动跳到函数的第一行位置,也叫步入,快捷键为F11
  4. 跳出当前函数,会直接执行当前函数到完毕,继续之前断点的执行,也叫步出,快捷键shift + F11
  5. 单步执行,可以理解为F10 + F11,即自动跳到下一个语句,如果碰到函数,会直接进入方法内部,快捷键为F9
  6. 停用断点,会使设置的所有断点全部失效(包括代码中的debugger),就好像没设置过一样,快捷键ctrl + F8
  7. 是否在遇到异常时暂停,如果选择在异常时暂停,那么发生异常的时候会自动暂停代码的执行,就好像在异常的地方打了断点一样,如果选择不在异常时暂停,那么即使发生异常,也不会暂停代码的执行
F12-开发者工具常用操作与使用说明之源代码sources_代码段_29

可以监测当前执行环境的作用域链上面的所有变量或表达式,比如求最大差值的一个函数.

F12-开发者工具常用操作与使用说明之源代码sources_控制台_30

我们可以监视任意合法的表达式,甚至可以进行赋值。

F12-开发者工具常用操作与使用说明之源代码sources_代码段_31

代码的原本执行结果应该是13,但是我们把min重新赋值之后,结果被改变了。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_32

而且放开断点之后,赋值语句会把原本属于局部变量的min,变为全局变量。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_33

断点(Breakpoints)

会显示出断点所在的行数与该行的内容,单击某一个断点会跳转到相应位置。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_34

并且可以通过右键进行一些其他的操作。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_35

作用域(Scope)

会展示出当前断点位置的作用域链上的所有变量。

F12-开发者工具常用操作与使用说明之源代码sources_控制台_36

如果是函数的话,会有本地变量,表示的是当前函数体内存在的变量。

脚本指的是可以访问的脚本中的变量,也包括其他脚本,比如上面的k、m、t就是我在另一个引入的js文件中定义的变量,不过如果引入的脚本在当前断点之后执行,那么这里就访问不到那些变量,也就不会在这里显示。

全局指的是挂在window下面的变量,由于我们声明的变量都是使用的let,因此不会变为window的属性,因此只属于脚本。如果将average用var来声明,那么就会在全局里面显示。

而且如果增加闭包的话,情况会有一些变化。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_37

我们发现多了一个闭包的变量区域,而且里面只有max,你可能会疑惑,上面的min变量也声明了呀,而且也已经赋值过了,为什么不显示呢?是因为min变量在闭包函数里面没有用到,在生成闭包环境时没有将min添加进去,因此当前作用域无法取得min的引用,请看此时控制台输出。

F12-开发者工具常用操作与使用说明之源代码sources_代码段_38

是不是这下就看明白了呢?通过这里我们对当前执行的代码作用域一目了然。

调用堆栈(Call Stack)

会展示出当前代码是在哪里调用的,如果有更高层的调用者,那么会一直展示,这样有利于我们快速找到业务中初始的调用位置。

我们来构造一个案例,看看它的效果。

F12-开发者工具常用操作与使用说明之源代码sources_代码段_39

XHR/提取断点(XHR/fetch Breakpoints)

可以根据设置的标识,在发起请求的时候,如果某个请求地址包含该标识,那么就会在该请求发起是自动进入断点。

注意这里只能是XHR或者fetch形式发起的请求才会有作用。如果是js或者css等类型,即使设置了也不会有效果。也可以不设置条件,来给所有请求执行断点。

假设我们有如下代码:

//9.js
var xhr = new XMLHttpRequest();
xhr.open("GET", "8.json");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
xhr.send();
//8.json
{
"name": "liu",
"sex": 0,
"age": 15
}

我们设置过滤条件为网址包含8.json

F12-开发者工具常用操作与使用说明之源代码sources_作用域_40

那么在加载页面的时候,包含这个标识的请求就会自动在发起的地方执行断点。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_41

如果不想添加标识去拦截所有请求,那么在点击添加之后,直接单击空白处即可。

DOM断点(DOM Breakpoints)

可以给DOM元素设置相应的断点条件,当触发该条件时会自动在代码执行的地方中断。

假设我们有如下代码:

//9.html
<body>
<div id="div" date-key="divKey">我就是我</div>
<input type="text" id="myInput">
<input type="button" value="点我" id="btn">
<script src="9.js"></script>
</body>
//9.js
document
.getElementById("btn")
.addEventListener("click",
function (e) {
document
.getElementById("div")
.classList
.add("active");
}
);

当我们给页面中的id为div的元素添加属性修改断点时:

F12-开发者工具常用操作与使用说明之源代码sources_代码段_42

我们看到面板中已经显示:

F12-开发者工具常用操作与使用说明之源代码sources_作用域_43

这时我们单击按钮,触发修改属性行为。

F12-开发者工具常用操作与使用说明之源代码sources_源代码_44

我们发现代码已经在第8行暂停执行了。

全局监听器(Global Listeners)

当我们设置一些全局事件的时候,会在该处显示,用于快速定位,哪里用到了全局的事件监听。可以进行暂时的移除操作。

假设我们有以下代码:

//9.js
window.onerror = function (e) {
console.log(e);
};
window.onfocus = function (e) {
console.log(e);
};
window.onload = function (e) {
console.log(e);
};

那么我们将看到:

F12-开发者工具常用操作与使用说明之源代码sources_控制台_45

事件监听器断点(Event Listener Breakpoints)

当某块代码触发了一些事件的时候,那么就会自动在该代码处执行断点,由于这块内容比较多,因此只举两个例子来供大家参考,其他的情况类似。

F12-开发者工具常用操作与使用说明之源代码sources_代码段_46

① 节点插入事件,假如我们有如下代码:

//9.js
document
.getElementById("btn")
.addEventListener("click",
function (e) {
let d = document.createElement('div')
d.id = "myDiv"
d.innerHTML = "新的div"
document.body.appendChild(d)
}
);
document.addEventListener("DOMNodeInserted",
function (e) {
console.log(e);
}
);

我们勾选上插入DOM节点的事件监听。

F12-开发者工具常用操作与使用说明之源代码sources_代码段_47

那么当我们点击按钮时,就会触发事件监听断点,在执行代码的地方执行断点。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_48

② 复制事件,假如我们有如下代码:

//9.js
document.addEventListener("copy",
function (e) {
console.log(e);
}
);

我们勾选上copy操作的事件监听。

F12-开发者工具常用操作与使用说明之源代码sources_作用域_49

那么当我们在页面中复制时,就会触发事件监听断点,在执行代码的地方执行断点。

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_50

CSP违规断点(CSP Violation Breakpoints)

如果服务端实现并设置了CSP的话,并且浏览器也支持该机制,那么会在执行一些不符合该策略的代码时,直接中断。

我们先在页面中使用meta的方式来模拟一下,以触发该策略。

比如我们有以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 注意这行代码即开启CSP策略 --><meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
<title>source源代码</title>
<style></style>
</head>
<body>
<div id="div" date-key="divKey">我就是我</div>
<input type="text" id="myInput">
<input type="button" value="点我" id="btn">
<script src="9.js"></script>
<script>
console.log('abc')
</script>
</body>
</html>
//9.js
eval("{}")
let func = new Function()
setTimeout(function() {
console.log(1)
})

我们会看到控制台报如下错误:

F12-开发者工具常用操作与使用说明之源代码sources_开发者工具_51

我们可以看到文件内部的style与script报出了错误,js中的eval也报出了错误,其实下面的new Function和setTimeout也是违反策略的,只不过eval报出的错误中断了代码的执行。

到此为止,关于开发者工具中源代码的功能已经基本全部讲解完毕,我们平时开发中离不开它,那就要好好的去了解它,充分的去使用它并发挥它的作用。

熟练的使用这些工具是我们需要掌握的技能,希望我能够给你一些帮助!

F12-开发者工具常用操作与使用说明之源代码sources_源代码_52

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK