拦截脚本加载

Intercepting script load

本文关键字:加载 脚本      更新时间:2023-09-26

我需要的是钩子/拦截其他外部JS加载。我可以把js放在文档

的任何地方

的例子:

<script src="hook.js"></script>
<script src="a.js"></script>
<script src="b.js"></script>

Hook.js应该拦截a.js和b.js。问题是,当hook.js执行时,我看不到其他脚本(文档)。脚本只包含hook.js)和document ready event is too late(脚本a.js和b.js被执行)。

是否有办法"看到"其他脚本标签,执行之前?谢谢你的帮助

编辑

  1. 我需要在hook.js中做任何"魔法",而不需要修改(静态)其他HTML。
  2. 没有jQuery

功劳在这里:https://stackoverflow.com/a/59424277/2016831您可以使用MutationObserver来查看哪些元素被添加到DOM中,当它们被添加时,只需更改源代码,或者如果它引用另一个URL,只需将其重定向到您自己的服务器,使用原始URL作为get参数,并以这种方式返回修改后的代码。

根据上面的答案,你可以这样做:

<script>
new MutationObserver((m, o) => {
  let potentialScript = document.querySelector("script + script");
  console.log(potentialScript.textContent);
  if(potentialScript) {
    o.disconnect();
    potentialScript
    .textContent = 
    potentialScript
    .textContent
    .replace(
      "})()",
      `
        window.wow = mySecretMethod;
        })()
      `
    );
    
    
  }
}).observe(
  document.body,
  {
    childList:1
  }
);
</script>
<script>
(function() {
  let mySecretMethod = () => {
    //does a bunch of evil secret stuff
    console.log("HA!");
  };
})();
wow()
</script>
<script>
console.log(wow())
</script>

或者你可以重定向HTTP请求与chrome扩展,见https://stackoverflow.com/a/61202516/2016831更多

如果我明白你想正确做什么…

如果您可以控制如何加载脚本A和B,最好的方法是将它们放置在与当前页面相同的域中(可能通过代理),通过AJAX加载文件,并以这种方式插入钩子。m.casey建议的jQuery之类的库可以使AJAX的细节和脚本的执行变得非常简单。

否则,Javascript实际上不具备与文档解析交互的能力(这就是导致脚本a和b在您的示例中被加载的原因,并且需要修改以"拦截"脚本加载),除非使用文档的邪恶。写来修改HTML流。当然,这只适用于同步加载hook.js(就像在示例代码中一样),加载到HTML而不是XHTML中,可以放置第二个钩子对修改后的HTML流进行后处理,并且确定HTML流不会逃离你的机制。

例如

.

<script id="hook1">document.write("<"+"textarea id='capture'>");</script>
<script src="a.js"></script>
<script src="b.js"></script>
<script id="hook2">document.write("<"+"/textarea");</script>
<script id="hook3">doSomethingWith(document.getElementById("capture").value)</script>

请注意,这是一个巨大的修改,你可能不应该这样做。

如果您正在使用jQuery,您可以让hook.js加载您希望拦截的脚本,如下所示:

$.getScript("a.js");
$.getScript("b.js");

这将动态地创建脚本标签,并且您将确定hook.js将始终继续a.js和b.js。