调试脚本通过jQuery getScript函数添加

Jam*_*ger 50 javascript debugging jquery visual-studio

我有一个页面,通过jQuery的$.getScript功能动态添加脚本引用.脚本加载并执行正常,所以我知道引用是正确的.但是,当我向任何脚本添加"调试器"语句以允许我在调试器(例如VS.Net,Firebug等)中单步执行代码时,它不起作用.似乎jQuery加载脚本的方式阻止了调试器查找文件.

有没有人为此解决这个问题?

Jam*_*ger 75

好的,事实证明,该$.getScript()函数的默认实现的工作方式不同,具体取决于引用的脚本文件是否在同一个域中.外部参考如:

$.getScript("http://www.someothersite.com/script.js")
Run Code Online (Sandbox Code Playgroud)

将导致jQuery创建一个外部脚本引用,可以毫无问题地进行调试.

<script type="text/javascript" src="http://www.someothersite.com/script.js"></script>
Run Code Online (Sandbox Code Playgroud)

但是,如果您引用本地脚本文件,例如以下任何一种:

$.getScript("http://www.mysite.com/script.js")
$.getScript("script.js")
$.getScript("/Scripts/script.js");
Run Code Online (Sandbox Code Playgroud)

然后jQuery将异步下载脚本内容,然后将其添加为内联内容:

<script type="text/javascript">{your script here}</script>
Run Code Online (Sandbox Code Playgroud)

这后一种方法并没有与我测试(视觉Studio.net,萤火虫,IE8调试器)任何调试工作.

解决方法是覆盖$.getScript()函数,以便始终创建外部引用而不是内联内容.这是执行此操作的脚本.我已经在Firefox,Opera,Safari和IE 8中对此进行了测试.

<script type="text/javascript">
// Replace the normal jQuery getScript function with one that supports
// debugging and which references the script files as external resources
// rather than inline.
jQuery.extend({
   getScript: function(url, callback) {
      var head = document.getElementsByTagName("head")[0];
      var script = document.createElement("script");
      script.src = url;

      // Handle Script loading
      {
         var done = false;

         // Attach handlers for all browsers
         script.onload = script.onreadystatechange = function(){
            if ( !done && (!this.readyState ||
                  this.readyState == "loaded" || this.readyState == "complete") ) {
               done = true;
               if (callback)
                  callback();

               // Handle memory leak in IE
               script.onload = script.onreadystatechange = null;
            }
         };
      }

      head.appendChild(script);

      // We handle everything using the script element injection
      return undefined;
   },
});
</script>
Run Code Online (Sandbox Code Playgroud)

  • 此代码不适用于$ .when.任何人都知道如何解决它? (3认同)

Eri*_*gar 18

使用JQuery 1.6(可能是1.5),您可以切换到不使用getScript,但使用jQuery.ajax().然后设置crossDomain:true,你将获得相同的效果.

错误回调将不起作用.所以你可能不会像下面那样设置它.

但是,我确实设置了一个计时器并成功清除它.所以说10秒后,如果我什么也听不到,我认为文件很糟糕.

        jQuery.ajax({
            crossDomain: true,
            dataType: "script",
            url: url,
            success: function(){
                _success(_slot)
            },
            error: function(){
                _fail(_slot);
            }
        })
Run Code Online (Sandbox Code Playgroud)

  • 我试过这个,这似乎有效.我确实在调试器中看到了JS源代码,我可以设置一个断点.但是有一个问题:每次我来回走动时,一个新的JS文件都会被新的ID#(script.js?_ = 2345678)等所装载.对此有任何解决方法吗? (2认同)

Ale*_*tov 14

对于那些想调试脚本并与$ .when一起使用的人(James Messinger的答案与$ .when不兼容)我建议使用这段代码:

var loadScript = function (path) {
  var result = $.Deferred(),
  script = document.createElement("script");
  script.async = "async";
  script.type = "text/javascript";
  script.src = path;
  script.onload = script.onreadystatechange = function (_, isAbort) {
      if (!script.readyState || /loaded|complete/.test(script.readyState)) {
         if (isAbort)
             result.reject();
         else
            result.resolve();
    }
  };
  script.onerror = function () { result.reject(); };
  $("head")[0].appendChild(script);
  return result.promise();
};
Run Code Online (Sandbox Code Playgroud)

所有的荣誉和荣耀都归功于Benjamin Dumke-von der Ehe和他的文章:jQuery脚本插入及其调试后果

这适用于$ .when,脚本是完全可见和可调试的. 谢谢.