我如何在chrome执行之前拦截JS代码

how can i intercept JS code before exectution in chrome

本文关键字:JS 代码 执行 chrome      更新时间:2023-09-26

我想创建chrome扩展到开发工具,我想拦截当前网页的JS代码之前,它是由浏览器编译或执行,实际上我想仪器JS代码之前,它在浏览器中运行。

谁能帮我们一下,这怎么可能呢?

没有办法挂钩到加载过程本身,但是具有未知类型的脚本不会作为脚本处理,这与具有自定义类型的脚本不执行这一事实相结合,是以下hack所依赖的。

调用window.stop将阻止文档在其轨道上加载,如果我们在文档的最顶部调用它,我们可以假设文档没有加载。

然后,我们可以发出一个XHR请求来获取文档的内容,并在将修改后的内容写入文档之前进行一些搜索和替换,通过为文档中的所有脚本提供自定义脚本类型来呈现惰性。

window.stop();
var request = new XMLHttpRequest();
request.open('GET', location.href);
request.onload = function(event) {
  var html = request.responseText
    .replace(/type='"text'/javascript'"/g, '')
    .replace(/<script/g, '<script type="x-instrument/javascript"');
  document.open();
  document.write(html);
  document.close();
};
request.send(null);
在这一点上,所有的脚本都是惰性的,一个基本的顺序加载器看起来像这样:
setTimeout(function next(index) {
  var script = document.scripts[index];
  if (script == null) {
    return setTimeout(callback, 0);
  }
  if (script.hasAttribute('src')) {
    var request = new XMLHttpRequest();
    request.open('GET', script.getAttribute('src'));
    request.onload = function() {
      var code = instrument(request.responseText);
      eval(code);
      setTimeout(next, 0, ++index);
    };
    request.send(null);
  } else {
    var code = instrument(script.textContent);
    eval(code);
    setTimeout(next, 0, ++index);
  }
}, 0, 0);

有了这个,任何页面都可以通过在文档的开头插入这个脚本来进行检测。

您也可以将其加载为chrome扩展中的内容脚本,但是,请确保run_at设置为document_start

{
  "manifest_version": 2,
  "name": "instrument",
  "version": "0.0.0",
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["instrument.js"],
      "run_at": "document_start"
    }
  ],
  "web_accessible_resources": [
    "instrument.js"
  ],
  "permissions": [
    "tabs", "<all_urls>"
  ]
}
示例