Chrome JavaScript调试 - 如何在页面刷新或代码中保留断点?

87

当我使用Chrome和它的JavaScript调试器时,每次重新加载我的页面/脚本时,我的断点都会丢失,我必须去弹出窗口中找到脚本文件,找到我的断点的代码行,点击添加等等。

有没有办法保存这些断点,使它们在页面刷新后仍然有效(我使用过的其他调试器可以实现这一点)?

或者,在我的JavaScript代码中是否有一种干净的方式可以输入某些内容,告诉Chrome开始跟踪(以暂停在某行代码上)?


3
Chrome 开发者工具应该在刷新后保留 JavaScript 断点。你是用 <script> 标签还是使用 XMLHttpRequest+eval 来引入 JavaScript?如果使用 XHR+eval,那么会失去断点。 - J. K.
在我的Mac上使用Chrome也遇到了几次这种情况。大多数时候断点都能正常工作,但有时刷新后断点就无法粘贴! - dano
如果脚本的查询字符串(例如缓存破坏器)发生更改,您还将丢失断点。关于 #hash 不确定。 - oriadam
9个回答

75
你可以放置一个 <div> 元素,给它设置 display: inline-block; 样式属性,这样它就可以包裹文本并且具有块级元素的属性。
debugger;

在大多数JavaScript环境中,它们很难被打断。它们肯定会持续存在。如果您正在使用调试器和console.log语句,则最好为生产环境准备一个可以消除这些调用的压缩工具。

在最新版本的Chrome浏览器中,控制台面板顶部的过滤器旁边有一个"保留日志"选项。在旧版本中,右键单击空白控制台窗口即可找到该选项("导航时保留日志")。当您没有console.log语句或硬编码调试器调用时,这很方便。

更新:我发现了一个名为chimney的工具,可以接受一个文件并删除所有console.log调用。它提供了如何删除调试器调用的好方法。


3
勾选“导航时保留日志”似乎是让Chrome恢复之前行为的关键。 - chrismarx
这里有一个不错的Web Workers替代方案:https://dev59.com/Z3E95IYBdhLWcg3wadKq#4985794 - Ege Özcan
我忘记了 debugger; 哈哈,浪费了半个小时来解决它。 - Eric Bishard
保留日志没有起作用。 - Kuronashi
@Kuronashi 如果你能找到选项但仍然无法工作,那么这意味着页面每次提供不同的(或命名不同的)js文件或捆绑文件。如果你正在使用框架或CMS,请确保没有启用缓存破坏开发插件。有些开发配置也可能会导致这种情况发生。 - Ege Özcan

45

设置断点,切换到网络选项卡并选择导航时保留日志切换按钮。现在在刷新页面后应该会保留断点。

或者使用JavaScript的方法是:

debugger;

21
此外,您是否会在向客户端发送JavaScript文件时,通过将当前纪元时间的附加查询参数添加到URL中?这是用于防止JavaScript文件被缓存。
当出现这种情况时,Chrome开发工具会在刷新后将该文件解释为不同的文件,这将(正确地)删除断点。
对我来说,删除查询参数使CDT在刷新后保留了断点。

3
谢谢!ExtJS 4包含一个"_dc"参数,以防止文件被缓存并在每次清除断点。将Ext.Loader.setConfig({ disableCaching: false, enabled: true });添加到应用程序配置中可以禁用它。 - Brian Topping
@BrianTopping 谢谢你的提示。他们为什么要这样愚蠢地附加动态查询参数以防止缓存呢?应该由浏览器(开发工具)/服务器来控制... - Juri
@sjogren_me,你是如何在Chrome Dev Tools中删除查询参数的? - jds
你是个英雄。一些弱鸡开发者发布了 date('His') 查询字符串,这让我想起来了! - lkraav

12

这可能是由于你正在动态加载或从其他脚本评估的脚本所导致的吗?我个人认为在我发现sourceURL属性之前,这种情况真的很恼人。在您要调试的脚本的最后一行放置以下特殊格式的注释将使其在Chrome中“锚定”,从而为其提供参考框架:

//# sourceURL=filename.js

您手动设置的断点现在将在页面重新加载时保留!这个惯例实际上起源于sourcemap规范,但至少Chrome将其作为独立技术来尊重。这里是一个参考


1
这就是我需要的那个答案。其他的回答需要改变库的行为(“删除查询参数”)或接受所有现有断点的丢失(“只需添加_debugger;_”),这两种方法都不是我认为 OP 想要的。绝对不是我想要的。在我的端上,原因是 js 文件都有时间戳,这让 Chrome 的 DevTools 感到困惑。感谢 @jtrick,因为我相信这是 OP 主要问题的主要答案,“有没有办法保存这些断点?” - Dr Sank
帖子中的参考链接已经失效。这是更新后的链接:https://developer.chrome.com/docs/devtools/javascript/source-maps/#sourceurl_and_displayname - Marco Sacchi

2

对于使用ExtJs 6.x的人:
在Ext.Loader中,您可以将"cache""disableCacheBuster"查询参数添加到页面的URL中,而不是使用disableCaching。这将从文件中删除"_dc"参数并启用Chrome调试器以保留断点。

请查看应用程序中的bootstrap.js(禁用缓存的配置参数)。


1
似乎还有一种通过在app.json中设置loader.cache: true的正式方式,https://www.sencha.com/forum/showthread.php?303932-Setting-a-breakpoint-in-Chrome-disappears-on-refresh-is-there-a-workaround - Saurabh

2
你可以在源代码中使用debugger;语句来让调试器在那里断点。

0

如@jtrick所说,请使用以下注释:

//# sourceURL=filename.js

这是在页面刷新和关闭/重新打开Chrome时保持断点持久性的最佳方法,即使在版本化(以控制浏览器缓存)或动态包含的JavaScript / CSS文件中也是如此。

这是更新的reference链接:

虽然不是Source Map规范的一部分,但@sourceURL允许您在使用evals时使开发变得更加容易。 这个帮助程序看起来非常类似于//# sourceMappingURL属性,并且实际上在Source Map V3规范中提到。

通过在代码中包含以下特殊注释,它将被evaled,您可以为inline脚本和样式命名,以便它们在DevTools中显示为更合理的名称。

//# sourceURL=source.coffee

如果您有一个服务器端缓存用于向浏览器提供版本化文件,则可以在缓存生成时在源代码中附加注释,而无需修改原始源文件。

注意: 在注释中,您还可以指定文件的虚拟路径,这样您就可以在 chrome devtools 的树形显示中组织动态加载或版本化的内容。即:

//# sourceURL=https://yourdomain.com/libs/ui/widget.js


0

Chrome开发者工具应该按照您的期望进行操作,但是您可以在(开发中的)代码中放置debugger;语句以暂停执行。


0

在你想要开始调试的代码之前,你可以加上debugger;。一旦页面开始加载,它会停在debugger;语句处。然后你可以根据需要轻松应用调试点。


1
这个答案重复了7年前已经有的几个答案。 - moopet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接