是否可以通过像WebKit、FireBug或IE8开发者工具这样的调试器来调试动态加载的JavaScript?

95

我最近的问题中,我已经为动态加载部分视图创建了一些JavaScript函数。但是我无法调试任何动态加载的JavaScript。因为所有加载的JavaScript都将由"eval"函数评估。

我发现一种方式是使用以下脚本来动态创建脚本到当前文档的头部。所有加载的脚本都将显示在HTML DOM中(您可以使用任何调试器找到它)。

var script = document.createElement('script')
script.setAttribute("type","text/javascript")
script.text = "alert('Test!');";

document.getElementsByTagName('head')[0].appendChild(script);

顺便说一下,大多数调试器(IE8开发者工具栏、Firebug和Google Chrome)无法在任何动态脚本中设置断点。因为可调试的脚本必须在页面加载后第一次加载。

当使用动态脚本内容或动态文件时,您有没有关于调试的想法?

更新1-添加用于测试的源代码

您可以使用以下xhtml文件来尝试调试someVariable值。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>    
    <title>Dynamic Loading Script Testing</title>
    <script type="text/javascript">
    function page_load()
    {       
        var script = document.createElement('script')
        script.setAttribute("id", "dynamicLoadingScript");
        script.setAttribute("type","text/javascript");
        script.text =   "var someVariable = 0;\n" +
                        "someVariable = window.outerWidth;\n" +
                        "alert(someVariable);";
        
        document.getElementsByTagName('head')[0].appendChild(script);
    }
    </script>
</head>
<body onload="page_load();">
</body>
</html>

根据回答,我在FireBug中进行了测试。结果应该显示如下所示的图片。

alt text

请查看页面加载后添加的“dynamicLoadingScript”。

alt text

但是它在FireBug的脚本选项卡中找不到。

更新2 - 在动态加载脚本中创建调试断点

alt text

alt text

以上两张图片显示在脚本的某一行中插入“debugger;”语句可以在动态加载脚本中触发断点。然而,两个调试器都不会在断点处显示任何代码。因此,这是无用的。

谢谢


你有没有找到这个问题的解决方案?我也遇到了同样的问题。 - adamJLev
尝试动态加载单独的文件,例如在此处查看实现http://queryj.com/2011/03/11/a-lightweight-script-loader/ - 我发现调试器可以更轻松地处理它。 - James Westgate
@infinity,请查看我的解决方案 - Molecular Man
3
2014 年的照片仍然无法显示 - 请问您可以重新上传吗? - TheGeekZn
我有一个类似的问题,但是因为图片无法显示,我无法确定。你能否更新一下图片? - Eric
11个回答

123

同样也可以使用Chrome进行相同的操作。Chrome有一个功能,您可以指定一个解析器属性,使动态JS片段显示为文件,然后可以通过浏览该文件并设置断点来调试。

需要设置的属性是

//# sourceURL=dynamicScript.js

dynamicScript.js应该是在脚本文件浏览器中显示的文件名。

更多信息请参见此处

Paul Irish 在他关于工具与Web应用开发栈的出色演讲中也进行了简要介绍。


5
如果某人在使用MVC3/Razor时遇到问题,请记得转义@符号,例如://@@ sourceURL=dynamicscript.js另外,以上内容也适用于Firebug。 - parsh
1
您也可以将此功能用于动态内联JavaScript。但是,如果该脚本中存在某些异常,您将无法在源列表中看到它。 - Roman Snitko
4
请注意,"//# sourceURL=dynamicScript.js" 是新的语法,将@更改为#。 - Cekk
3
Chrome 开发者工具中关于源映射(Source Maps)的更新链接为:https://developer.chrome.com/devtools/docs/javascript-debugging#breakpoints-dynamic-javascript。请注意,翻译保持原意且通俗易懂,不包含解释或其他非翻译内容。 - chrismarx
3
对我来说,JS文件显示在名为“(无域)”的分组中,值得一提的是我一开始没注意到这个! - JMac
显示剩余3条评论

21

尝试在你动态添加的JavaScript中添加一个"debugger;"语句。这应该会导致它在那一行停止执行,而不管断点设置如何。


我能找到的只有这个:http://code.google.com/p/fbug/issues/detail?id=1259。顺便说一下,我使用脚本标签添加到头部来动态加载脚本(但使用src属性),以这种方式添加的代码在所有浏览器上都可以进行调试,即使它没有与初始页面一起加载。 - Joeri Sebrechts
你使用的添加脚本标签的确切代码是什么?我遇到了与 OP 相同的问题,这使得在 Chrome 中无法调试动态加载的 JS 文件。谢谢! - adamJLev
var loaderNode = document.createElement("script"); loaderNode.setAttribute("type", "text/javascript"); loaderNode.setAttribute("src", url); document.getElementsByTagName("head")[0].appendChild(loaderNode); - Joeri Sebrechts

19

是的,现在可以使用Google Chrome调试动态加载的JavaScript!

不需要为动态加载的JS文件添加额外的 debugger; 或其他属性。只需按照以下步骤进行调试:

方法1:

我的技术负责人刚刚展示了一种超级简单的调试动态加载JavaScript方法的方法。

  1. 打开Chrome控制台并输入方法名称,然后按Enter键。
    在我的情况下,它是 GetAdvancedSearchConditonRowNew
    如果JS方法已加载,则将显示该方法的定义。

输入图像描述 here


  1. 单击方法的定义,整个JS文件就会打开以供调试 :)

输入图像描述 here


方法2:

例如,我在点击按钮时使用ajax调用加载JS文件。

  1. 在Google Chrome开发工具中打开 network 选项卡
  2. 单击控件(例如按钮),该控件将加载某些JavaScript文件并调用某些JavaScript函数。
  3. 观察网络选项卡,查找该JS函数(在我的情况下是 RetrieveAllTags?_=1451974716935
  4. 将鼠标悬停在其 initiater 上,您将找到您动态加载的JS文件(带有前缀 VM * )。

chrome中调试动态加载的JavaScript -1


  1. 点击那个 VM* 文件来打开。
  2. 在文件中加入调试器,随意放置 :D

chrome中调试动态加载的JavaScript -1



谷歌让这个变得如此晦涩难懂,真是可耻。但你成功解决了问题,值得赞扬!(Kudos是“荣誉、赞扬”的意思,与Shame相反) - toddmo

15
我正在使用谷歌浏览器进行这个目的。
在 Chrome 的 "脚本" 选项卡中,您可以启用“暂停所有异常”功能。
enter image description here
然后,在代码中某个位置放置一行try{throw ''} catch(e){}。Chrome 将在执行到此行时停止运行。
编辑:修改了图片以更清楚地说明我所说的内容。

在Google Chrome中进行开发时,您应该插入一些文本,以指示当前动态脚本的名称,当jQuery或任何其他加载脚本将脚本附加到DOM时,就像我向jQuery团队报告的那样。但是我没有时间去处理它。http://bugs.jquery.com/ticket/8292 - user94893
@Soul_Master,但是使用我的方法,您不需要插入文本。您可以在动态脚本行中插入try{throw ''} catch(e){},然后启用“暂停所有异常”模式,Chrome将在抛出异常时停止执行。我已经多次检查过了。我加载了另一张图片。那里更清楚地说明了我在说什么。 - Molecular Man
在Chrome中,当调试面板打开时,您可以使用“debugger;”语句来在语句处中断。如果调试面板关闭,Chrome将简单地忽略此语句。 - dinesh ygv
@dineshygv,现在你可以……了。但是3年前你做不到。当时在动态创建的脚本中,debugger无法工作。 - Molecular Man

10

是的,我看到了。我已经向jQuery团队报告了这个漏洞很长时间了。 http://bugs.jquery.com/ticket/8292 - user94893
1
警告!所描述的技术将导致IE7出错,请在生产环境中不要保留//@ sourceURL=blah - Jethro Larson
很可能是“调试器”部分引起了问题,而不是源代码注释(这显然被JS忽略了)。 - Kyle Simpson
它可能会导致ie条件编译方面的问题。例如:http://www.javascriptkit.com/javatutors/conditionalcompile.shtml - Jethro Larson

4

更新: sourceUrl语法已更改(@被#替换),以避免在不支持的浏览器(即IE)上出现错误详情请见


2
使用您提供的代码以及像这样的调试器语句,使用Chrome(12.0.742.112)
    script.text =   "debugger;var someVariable = 0;\n" +
    "someVariable = window.outerWidth;\n" +
    "alert(someVariable);";

chrome_debugger

这对我来说可行。

在执行JavaScript之前,我需要修改一些内容(将所有jQuery选择器的范围限制为当前部分视图div)。

如果您将选择器更改绑定到部分视图上的事件而不是在HTML body中创建脚本元素(感觉不太对),那么它可能更具体。

您可以像这样做:

   (function(j)(
      var limiting_selector = '';
      j(".partial_views").bind('focusin over',function(e){
         limiting_selector = j(this).attr('someattr') // or j(this).data('limiting-selector')
      }).bind('focusout out',function(e){
         limiting_selector = '';
      });
      // And then go on with
      // j(limiting_selector+' .someclass')
   ))(jQuery)

这段代码将始终向所有jQuery选择操作添加一个限制选择器,只要鼠标在给定元素内,前提是HTML没有被搞砸。

(仍然看起来有点hackish,也许有更好的解决方案)

干杯!


1

动态加载的 JavaScript 仍然需要被浏览器解析,这就是 WebKit 或 FireBug 调试器所在的位置,因此不管怎样都会受到调试器的影响,我认为 IE8 中的开发者工具也是如此。

因此,您的代码会受到调试器的影响,因此如果没有错误,出现问题的地方将不会在该文件或文本中。

另一件事是script.text = "alert('Test!');"; 是无效的,所以它在所有浏览器中都不起作用,你想要的是 script.innerHTML = "alert('Test!');";

即使它是 innerHTML,它也意味着 HTML 标签内的代码而不是 HTML 内部的内容,只有大多数人将其用于此,所以会被解释错误。

更新二进行了编辑

第二次更新时我使用了 Chrome,我做了以下操作:

输入 about:blank 打开控制台并粘贴:

var script = document.createElement('script')
script.setAttribute("type","text/javascript")
script.innerHTML = "alert('Test!');debugger;";

document.getElementsByTagName('head')[0].appendChild(script);

然后它会中断并打开脚本选项卡,显示about:blank(什么也看不到)

然后在右侧显示调用堆栈列表,然后点击第二个(匿名函数),它将向您显示。

因此,在您的文件中,您将有一个(匿名函数)是您正在运行的代码,并且您将在其中看到断点。这样,您就知道在正确的位置。


1
在Firebug中,您应该能够在页面加载和脚本注入后看到该脚本。当您这样做时,您可以在适当的位置设置断点,并且在刷新页面时它将被保留。

你说得对。那样不起作用。我尝试使用eval()和Firebug,当您使用它时,Firebug将允许您设置断点。您不能使用eval()并需要设置脚本标记的原因是什么?更一般地说,您不能将此动态JavaScript作为单独的.js文件提供在您的服务器上吗?您正在尝试解决什么问题? - Moishe Lettvin
在执行JavaScript之前,我需要修改一些内容(将所有jQuery选择器的作用域限制在当前局部视图div中)。您有任何解决我最近问题的想法吗?更多信息请查看我最近的问题。 - user94893

0
使用 Google Chrome(或 Safari)开发者工具,您可以逐行运行 JavaScript 代码。

开发者工具 > 脚本 > 选择要调试的脚本 > 在右侧点击暂停标志 或通过单击 行号 设置断点。

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