通过Getscript检索的脚本无声地失败 - 如何排除故障?

时间:2014-10-21 04:25:24

标签: javascript jquery ruby-on-rails

我在页面加载后运行脚本。这不能通过预编译的资产管道来完成,因为在页面加载的控制器中生成的ruby变量在脚本中使用。以下是我调用脚本的简化版本:

<script type='text/javascript' charset='utf-8'>
  var url = "/assets/foo/bar.js";
  $(window).on('load', function(){
    console.log('page-loaded and url is: ' + url);
    $.getScript( url, function() {
      console.log('loaded bar.js');
    });
  });
</script>

行为是第一个console.log在页面加载时触发,但getScript中的第二个从不运行。

由于我在第一个控制台日志中显示了url,我可以获取控制台输出中显示的值,将其粘贴到浏览器的地址栏中(在域名之后),并成功将脚本加载到页面中文本 - 所以url引用没问题。

接下来,我将脚本(在此示例中为bar.js)缩减为输出ruby变量的单个console.log语句。这是有效的,所以我的原始js中必定存在错误,但在任何控制台输出中都没有显示错误。

我如何排除这个javascript的问题,在javascript控制台(在firefox开发工具中)或在rails控制台中出现的错误类型/行#不存在? Rails会在其他地方记录错误吗?

请注意,rails-console中没有任何迹象表明getScript已经/加载了任何东西 - 使用工作脚本或神秘破坏的脚本,因为如果这是一个像这个问题的ajax调用那样:

How to troubleshoot silently failing js in Rails?

我没有包含js文件,因为我不需要帮助排除javascript 的帮助,如果我可以获得有关错误性质的反馈。如何让错误显示在某个地方?

编辑 - 我试着用内联粘贴脚本代替'getScript'调用。它仍然无声地失败。唯一的区别是我从脚本中的中得到了第一个console.log()输出,并且页面上的其他一些东西中断了,之前有效,表明js错误,这仍然是未报告的谜

编辑#2:

来自@ jfriend00建议#9的三个错误是:

SyntaxError: missing ; before statement

Stack trace:
.globalEval/<@http://127.0.0.1:3000/assets/jquery.js?body=1:339:5
.globalEval@http://127.0.0.1:3000/assets/jquery.js?body=1:340:1
.converters["text script"]@http://127.0.0.1:3000/assets/jquery.js?body=1:9739:4
ajaxConvert@http://127.0.0.1:3000/assets/jquery.js?body=1:8809:8
done@http://127.0.0.1:3000/assets/jquery.js?body=1:9226:4
.send/callback@http://127.0.0.1:3000/assets/jquery.js?body=1:9686:8
 new:234
Object { readyState: 4, getResponseHeader: .ajax/jqXHR.getResponseHeader(), getAllResponseHeaders: .ajax/jqXHR.getAllResponseHeaders(), setRequestHeader: .ajax/jqXHR.setRequestHeader(), overrideMimeType: .ajax/jqXHR.overrideMimeType(), statusCode: .ajax/jqXHR.statusCode(), abort: .ajax/jqXHR.abort(), state: .Deferred/promise.state(), always: .Deferred/promise.always(), then: .Deferred/promise.then(), 11 more… } new:235

"parsererror"

很高兴知道WHICH语句缺少分号(我没有看到任何遗漏),或者如果此错误在解析器本身内,由于脚本中的某些内容会导致错误解析。

编辑#3 - 尝试了更多@ jfriend00建议 如果我将脚本内联,以便使#11成为可能,因为我的脚本调用另一个由数千行组成的jquery函数。不过,对于没有外部的小脚本来说会很棒。

对于#10 - 我在最后放了一个console.log()。内联版本运行到最后并显示该输出,但只是不执行任何其他应该执行的操作。然而,getScript方法永远不会运行或回调任何东西,除非通过错误方法(在编辑#2中列出),验证在这种情况下检测到错误。 IOW,相同的脚本代码'运行但不起作用'内联,但如果由getScript检索则为'errors-out'。

我想我只需将所有特定于页面的脚本放在内联并接受丑陋。然后,我可以在每个阶段添加console.log()s来输出'二进制搜索'方法,以输出每个可能的数据位,因为它是随机机会猜测,以确定哪个设置/值导致任何问题。

1 个答案:

答案 0 :(得分:1)

由于我们无法真正知道造成问题的原因,我们所能做的最好的事情就是列出一堆东西供你检查:

  1. 您的脚本是否正在进行document.write()次调用,因为在文档加载完成后这样做会清除当前文档并隐藏正在发生的事情。

  2. 您正在加载的脚本是否可能实际上除了定义等待调用的函数之外还执行任何操作。

  3. 您是否尝试使用静态脚本标记加载脚本以查看它是否以这种方式工作?这也会使它处于顶层(不在$.getScript()的内容中,您可能更有可能看到任何脚本错误。

  4. 您是否200%确定传递给$.getScript()时路径是否正确?

  5. 您是否查看了Chrome调试器中的网络标签,了解实际上是从服务器请求和返回的内容?您应该看到请求已经发出并且回复了。

  6. 您是否清除了浏览器缓存,以防文件的旧版本或许空文本卡在缓存中? Chrome中的网络选项卡还会告诉您文件是从服务器还是从缓存加载的。您可以在URL中添加一个随机数来阻止缓存:

    var url = "/assets/foo/bar.js?" + Math.random();

  7. 这需要一些时间,但您可以在最简单的jQuery版本中逐步浏览$.getScript()。你必须弄清楚在哪里设置断点,因为响应是异步回来的,但这最终会让你看到它得到的确切响应以及响应的内容。

  8. 如果你把$.getScript()的完成回调作为第二个参数,那个回调报告的参数是什么?

    $.getScript(url, function(data, textStatus, jqXhr) { console.log(textStatus); console.log(data); console.log(jqXhr); });

  9. 如果在$.getScript()上设置错误处理程序,是否会调用它?

    $.getScript(url).fail(function( jqxhr, settings, exception) { console.log(exception); console.log(jqxhr); console.log(settings); });

  10. 如果您确定脚本已开始执行,但随后失败,则可以调试该脚本。这样做的简单方法是使用唯一的console.log()语句来填充它,这样您就可以准确地看到它到达了多远并迭代到更精细和更精细的行号,直到您确切地缩小它的失败位置(本质上是二元搜索)。

  11. 您还可以在脚本顶部附近的动态加载脚本中放置debugger;语句以触发调试器,然后您可以单步执行脚本的其余部分以查看其失败的位置。 / p>