如何调试外部Eval脚本

时间:2013-12-23 00:31:00

标签: javascript google-chrome-devtools

具体示例:How Big is Your Haystack?

中的haystack.js脚本

我搜索了一个答案,似乎所有内容都指向使用//# sourceURL=name.js评论。然而,如何实现这一点的机制让我望而却步(也许我只是密集)。

每个人总是指向Debugging JavaScript,但演示被破坏(同源错误)。其他常见示例不提供使用此类外部脚本的见解。

我尝试使用Live Edit插入sourceURL注释,但到目前为止,eval脚本从未显示在Sources选项卡中。

有人请指导我完成此任务的步骤吗?

更新:事实证明这是一项有趣而烦人的尝试。由于以下复杂情况,这个特定的网站使任务变得不必要:

  • haystack.js脚本包含document.write()语句(加载其他使用的脚本)。必须在重新加载脚本之前删除它们,否则清除DOM。

  • 作者在代码上使用了一种奇怪的反引号密码形式的混淆。因此,在删除模糊处理之后,但在进行eval之前,必须进行代码修改(包括sourceURL)。

我克服了部分解决方案。将jQuery加载到页面后,我运行此脚本:

$.ajax({
  url: '/js/haystack.js',
  dataType: 'text'
}).done(function(data) {
    // Remove document.write() statements and append sourceURL comment after obfuscation is removed
    var refactored = data.replace(/return d/, "return d.replace(/document\.write[^;]+;/g, '') + '\\n//# sourceURL=haystack.js\\n';");
    $('head').append('<script type="text/javascript">' + refactored + '</script>');
});

DevTools Source Tag after script

现在haystack.js出现在Sources选项卡的(无域)树中。可以设置断点,但存在奇怪的行为。似乎DOM事件处理程序仍然绑定到原始脚本(从未到达重新加载的脚本处理程序中的断点)。执行pageInit()再次将处理程序重新绑定到修改后的脚本,但页面更新仍然不稳定。不确定为什么这种行为仍然存在。我可以单步执行代码,一切看起来都很正常,但页面更新似乎落后于代码。事实上,代码几乎违反了每个javascript最佳实践,这无疑是一个因素。

1 个答案:

答案 0 :(得分:3)

这个问题真的让我很感兴趣。我希望我的回答有所帮助。我从Set breakpoints and debug eval'd JavaScript开始,然后稍微扩展了一下

以下是plunker

比使用eval更好,您可以将脚本元素插入到文档中。

var js = "console.log('this is line 1');"
addCode(js); // Right now! Debuggable!

// Dynamically evaluate JavaScript-as-string in the browser
function addCode(js){
  var e = document.createElement('script');
  e.type = 'text/javascript';
  e.src  = 'data:text/javascript;charset=utf-8,'+escape(js);
  document.head.appendChild(e);
}

然后它会显示在来源标签中:

enter image description here

使用eval也可以通过在末尾添加行//@ sourceURL=dynamicScript.js来实现

请参阅此plunker

var js = "console.log('this is line 1');\n" +
"//@ sourceURL=dynamicScript.js;"
addCode(js); // Right now! Debuggable!

// Dynamically evaluate JavaScript-as-string in the browser
function addCode(js){
  eval(js);
}

请注意,该脚本列在(无域)源文件夹下。