通过Getscript检索的脚本静默失败-如何解决此问题

Script retrieved via Getscript Fails Silently - how to troubleshoot this?

本文关键字:何解决 解决 问题 检索 Getscript 脚本 失败 静默 通过      更新时间:2023-09-26

页面加载后,我正在运行一个脚本。这不能通过预编译的资产管道来完成,因为脚本中使用了页面加载时在控制器中生成的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中的第二个console.log从未运行。

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

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

如果javascript控制台(在firefox-dev工具中)或rails控制台中没有显示错误类型/line#,我该如何对该javascript进行故障排除?Rails是否在其他地方记录错误?

请注意,rails控制台中没有任何迹象表明getScript做了/加载了任何东西——无论是使用工作脚本还是神秘损坏的脚本,如果这是一个类似以下问题的ajax调用:

如何解决Rails中静默失败的js?

我不包括js文件,因为如果我可以得到关于错误性质的反馈,我就不需要帮助对javascript进行故障排除。如何使错误显示在某个位置?

EDIT-我尝试以内联方式粘贴脚本,以代替"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"

如果知道哪个语句缺少分号(我看不到任何丢失),或者这个错误是否在解析器内部,是由于脚本中的某些内容导致错误解析,那就太好了。

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

对于#10-我在末尾放了一个console.log()。内联版本运行到最后并显示输出,但不做它应该做的任何其他事情。然而,getScript方法从不运行或调用任何东西,除非通过错误方法(在上面的Edit#2中列出)来验证在这种情况下是否检测到错误。IOW,相同的脚本代码"运行但不工作"内联,但如果由getScript检索到,则"出错"。

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

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

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

  2. 您正在加载的脚本除了定义等待调用的函数之外,是否可能实际上没有做任何其他事情。

  3. 你有没有试过用静态脚本标签加载脚本,看看它是否能正常工作?这也会使它处于顶级(而不是在$.getScript()的内部,在那里你可能更容易看到任何脚本错误

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

  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;语句,以触发调试器,然后您可以遍历脚本的其余部分,查看它在哪里失败。