是否有替代Chrome DevTools扩展的preprocessorScript?

时间:2016-05-25 07:02:29

标签: javascript google-chrome-extension google-chrome-devtools

我想为Javascript创建一个自定义探查器作为Chrome DevTools扩展。为此,我必须检测网站的所有Javascript代码(解析为AST,注入钩子,生成新源)。使用此处描述的chrome.devtools.inspectedWindow.reload()及其参数preprocessorScript可以轻松实现这一点:https://developer.chrome.com/extensions/devtools_inspectedWindow

不幸的是,此功能已被删除(https://bugs.chromium.org/p/chromium/issues/detail?id=438626),因为没有人使用它。

您是否知道我可以通过Chrome扩展程序实现同样的目标?有没有其他方法可以用更改的版本替换传入的Javascript源?这个问题非常具体针对Chrome扩展程序(可能是其他浏览器的扩展程序),我在将其作为最后的手段之前将其作为最后的手段(例如专用应用程序)。

2 个答案:

答案 0 :(得分:1)

在HTTP上,您可以使用chrome.webRequest API将JS代码请求重定向到包含已处理JavaScript代码的数据URL。

但是,这不适用于内联脚本标记。它也不适用于HTTPS,因为数据URL被认为是不安全的。 Chrome中的数据网址不能超过2MB,因此您将无法重定向到大型JS文件。

如果每个脚本的确切执行顺序不重要,您可以取消脚本请求,然后再将包含脚本内容的消息发送到页面。这将使其适用于HTTPS。

要解决这两个问题,您可以将HTML页面本身重定向到数据网址,以获得更多控制权。这有一些负面影响:

  1. 无法重新加载页面,因为网址已固定为数据网址
  2. 需要添加或更新<base>代码,以确保样式表/图片网址转到正确的网址
  3. 打破需要cookie /身份验证的ajax请求(不确定是否可以修复)
  4. 不支持对数据网址的localStorage
  5. 不确定是否有效:为了修复#1和#4,您可以考虑在Chrome扩展程序中设置HTML页面,然后将其用作基页而不是数据网址。

    可能有效或无效的另一个想法:使用chrome.debugger修改源代码。

答案 1 :(得分:1)

使用Chrome调试协议。

首先,使用DOMDebugger.setInstrumentationBreakpointeventName: "scriptFirstStatement"作为参数,为每个脚本的第一个语句添加一个断点。

其次,在调试器域中,有一个名为scriptParsed的事件。收听它,如果被呼叫,请使用Debugger.setScriptSource来更改来源。

最后,每次使用Debugger.resume编辑源文件后,请致电setScriptSource

半伪代码中的示例:

// Prevent code being executed
cdp.sendCommand("DOMDebugger.setInstrumentationBreakpoint", {
  eventName: "scriptFirstStatement"
});

// Enable Debugger domain to receive its events
cdp.sendCommand("Debugger.enable");

cdp.addListener("message", (event, method, params) => {
  // Script is ready to be edited
  if (method === "Debugger.scriptParsed") {
    cdp.sendCommand("Debugger.setScriptSource", {
      scriptId: params.scriptId,
      scriptSource: `console.log("edited script ${params.url}");`
    }, (err, msg) => {
      // After editing, resume code execution.
      cdg.sendCommand("Debugger.resume");
    });        
  }
});

上述实施并不理想。它应该可以监听断点事件,使用关联的事件数据访问脚本,编辑脚本然后继续。听scriptParsed然后恢复调试器是两件不应该在一起的事情,它可能会产生问题。然而,这是一个更简单的例子。