小编典典

从Chrome上的Greasemonkey脚本向页面中注入JS函数

javascript

我有一个Greasemonkey脚本,可以在Firefox和Opera中正常工作。但是,我很难使它在Chrome中工作。问题是将一个函数注入页面,该函数可以由页面中的代码调用。到目前为止,这是我正在做的事情:

首先,我获得了针对Firefox的unsafeWindow的帮助程序参考。这使我可以为FF和Opera(和Chrome,我认为)具有相同的代码。

var uw = (this.unsafeWindow) ? this.unsafeWindow : window;

接下来,我将一个函数注入页面。它实际上只是一个非常薄的包装器,除了在我的GM脚本的上下文中调用相应的功能外,什么也不做:

uw.setConfigOption = function(newValue) {
    setTimeout(setConfigOption, 0, newValue);
}

然后,在我的脚本中有相应的功能:

setConfigOption = function(newValue) {
    // do something with it, e.g. store in localStorage
}

最后,我将一些HTML注入到页面中,并带有一个调用该函数的链接。

var p = document.createElement('p');
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>';
document.getElementById('injection-point').appendChild(p);

总结一下:在Firefox中,当用户单击注入的链接时,它将在unsafeWindow上执行函数调用,然后触发超时,该超时将在我的GM脚本的上下文中调用相应的函数,然后进行实际处理。(如果我错了,请纠正我。)

在Chrome中,我仅收到“ Uncaught ReferenceError:未定义setConfigOption”错误。实际上,在控制台中输入“
window.setConfigOption”会产生“未定义”。在Firebug和Opera开发者控制台中,该功能就在那里。

也许有另一种方法可以执行此操作,但是我的一些函数是由页面上的Flash对象调用的,我认为这使我有必要在页面上下文中使用函数。

我快速浏览了Greasemonkeywiki上unsafeWindow的替代方案,但它们看上去都很难看。我是在这里完全走错了路还是应该更仔细地研究这些?

为了使该hack的额外丑陋更容易忍受,我现在至少可以放弃使用unsafeWindow和wrappedJSObject。

我仍然没有设法使Greasemonkey Wiki的内容范围运行器正常工作。它应该做同样的事情,看起来似乎执行得很好,但是<a>例如,页面中的元素永远无法访问我的函数。我还没有弄清楚为什么会这样。


阅读 624

收藏
2020-05-01

共1个答案

小编典典

与Chrome中运行在页面上的代码进行通信的唯一方法是通过DOM,因此您必须使用黑客手段,例如<script>在代码中插入标签。请注意,如果您的脚本需要先运行页面上的所有其他内容,则这可能会引起问题。

编辑: 这是NiceAlert扩展程序执行此操作的方式:

function main () {
  // ...
  window.alert = function() {/* ... */};
  // ...
}

var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);
2020-05-01