拦截脚本加载

时间:2014-07-17 16:51:45

标签: javascript

我需要的是挂钩/拦截其他外部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时,我看不到其他脚本(document.scripts只包含hook.js),文档就绪事件太晚了(执行脚本a.js和b.js)。

在执行之前,有没有办法“看到”其他脚本标签? 谢谢你的帮助

修改

  1. 我需要在hook.js中做任何“魔术”而不用静态(静态)其他HTML。
  2. 没有jQuery

3 个答案:

答案 0 :(得分:1)

如果我明白你要做的正确...

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

否则,Javascript实际上无法与文档的解析进行交互(这是导致脚本a和b在您的示例中加载的原因,以及需要修改为“拦截”脚本的内容loading),除了使用document.write的邪恶来修改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>

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

答案 1 :(得分:0)

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

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

这将动态创建脚本标记,您可以确定hook.js将始终继续a.js和b.js。

答案 2 :(得分:0)

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

根据以上答案,您可以执行以下操作:

<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>

或者,您也可以使用chrome扩展名重定向HTTP请求,有关更多信息,请参见https://stackoverflow.com/a/61202516/2016831