页面刷新前的断点?

54

我正在调试一些第三方压缩的JavaScript代码,其中某处会触发浏览器页面刷新。但是,我无法确定哪部分代码导致了刷新。

有没有一种在Chrome中设置断点的方法,可以在页面刷新之前命中该断点,以便我检查调用堆栈并查看引起刷新的原因?


2
你可以尝试使用自定义的 onunload 监听器并在那里中断。 - Marvin
1
你可以生成一个堆栈跟踪,并查看触发重新加载的涉及的函数。 链接 - Lix
2
你可能已经知道了。在Chrome的控制台中有一个复选框,可以使日志在重新加载后不清除。 - Blaž Zupančič
1
我尝试了onunloadonbeforeunload,但调用栈为空。 - Thomas Johnson
3
你试过使用 https://dev59.com/02ct5IYBdhLWcg3wFpm1#12419326 吗? - jcuenod
7个回答

67

尝试以下方法:

  1. 打开Chrome开发者工具
  2. 导航至“Sources”选项卡
  3. 在右侧面板中,展开“Event Listener Breakpoints”
  4. 展开“Load”树
  5. 选中beforeunloadunload选项

看看是否有所帮助;如下图所示。

Chrome Dev Tools with Suggested Event Listener Breakpoints Checked

编辑:或者,如果这不起作用,您可以使用Chrome搜索所有已加载的脚本以查找可能负责的代码。显然有许多用JavaScript刷新页面的方法,但它们大多具有一些常见字符串,例如“navigator”,“location”,“reload”,“window”。

最后,如果有指向您正在访问的同一个页面的链接,则可能会触发JS单击它- 不太可能,但如果迄今为止没有其他方法奏效,这个值得探索......

(请原谅我的格式,因为我在移动设备上...)

注意:偶尔会出现这种情况,由于我还没有完全理解的原因,这种解决方法未能真正导致调试器暂停;在这种情况下,我发现thorn̈ 对这个问题的答案对我很有帮助。


1
它不会泄漏导致刷新的代码片段。 - Siddharth
1
抱歉 @Siddharth,我不确定你的意思是什么? - Alexander Nied
我的意思是,OP想要检测导致页面刷新的代码片段,你放置这些事件的方式很好,但无论如何,我们都无法知道触发刷新的代码位置,希望你现在有更好的想法了。 - Siddharth
@Siddharth - 感谢您的澄清。只要调试器触发,我认为我们应该能够在开发工具中跟踪它--即使不是我们调试的行,我们也应该能够在开发工具中沿着堆栈追踪它。您是否不同意? - Alexander Nied
@silviubogan - 这很奇怪-- 你确定没有在调用堆栈中列出任何脚本吗?如果没有,那么触发页面刷新的脚本可能只有一个级别,如果您使用所有可用方法得到这个结果,那么这似乎就是正在发生的事情。我同意,如果您处理没有源映射的最小化代码,那么您将度过难关--无论原因如何,这都将是_任何_调试的情况。祝你好运。 - Alexander Nied
显示剩余2条评论

37
在Firefox开发者工具中(注意不是Chrome;更新于2020:现在Chrome也可使用此方法),进入控制台,输入addEventListener('beforeunload',()=>{debugger}),然后执行你的代码。当调试器停止在debugger语句时,查看调用堆栈。你将看到是什么触发了该事件。Chrome中没有类似功能。

至少对我来说这个方法有效。


4
这个方法在Chrome 79中也适用!就我而言,问题是由一个调用window.location.reload();的脚本(无意间)引起的。奇怪的是,“DOM断点”功能竟然没有让调试器在beforeunloadunload上断下来。 - Dai
1
@silviubogan 这很可能意味着在您的情况下,位置不是由JS更改的。 - thorn0
1
在Chrome 83中对我有效。我刚刚重新检查了一下:addEventListener('beforeunload',()=>{debugger});function foo(){window.location.reload()};foo() 调用堆栈正确显示。 - thorn0
1
有趣的是,我遇到了与@Dai相同的情况,即使在Chrome上,我的解决方案也无法为我工作。 在这种情况下,这个答案确实起作用了,我能够继续调试。 - Alexander Nied
1
我也是@AlexanderNied,但我真的不明白为什么你的解决方案不起作用,因为它应该完全相同。 - loic_amphibee
显示剩余3条评论

8
在开发工具中,切换到网络面板,打开“保存日志”,仔细查看初始化列。

在我的情况下,发起者列只显示页面加载的“其他”。 - Luke Hutchison

3
您没有说明第三方库是做什么的。如果它是一个 UI 组件,比如广告或类似的东西,只需将其放在一个 iframe 中,并将 sandbox 属性配置为您需要的即可。https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe(向下滚动到沙盒属性部分)
如果它是由事件触发的东西,只需在 Chrome 开发工具中使用 getEventListener() 函数并跟随 listener 路径...(困难,但可能) 例如:

enter image description here

listener 属性将引导您到将被调用的实际函数。然后,您可以在混淆代码中搜索它们并添加调试器以了解其目的。
还有许多其他场景 - 如果您能更具体地说明会更好。

0

需要考虑的事项:

  • 是否有链接被点击?
  • 是否有表单被提交?

在我的情况下,是一个包含内容的表单元素。


0
在我的情况下,没有任何代码。这就是为什么我在搜索时找不到任何东西的原因。
刷新是由HTTP头引起的:refresh: 60;
它无法通过JS移除,但我能够停止刷新:
window.stop();

0

对于识别重定向源的问题,这些解决方案都没有起作用。

最后我发现问题是由于我点击的元素上的href="#"引起的。该元素上还有一个onClick事件,导致重定向到另一个页面。移除href="#"解决了我的问题。

在使用AngularJS时,这不是一个问题,但在切换到React后,点击操作开始引发新的重定向。


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