我正在编写一个 Greasemonkey 脚本,我想在其中重载 XMLHttpRequest.prototype.open
函数来劫持页面上的 Ajax 调用。
我使用以下代码:
// ==UserScript==
// @name name
// @namespace namespace
// @description desc
// @include https://url*
// @version 1.0
// ==/UserScript==
if (XMLHttpRequest.prototype) {
//New Firefox Versions
XMLHttpRequest.prototype.realOpen = XMLHttpRequest.prototype.open;
var myOpen = function(method, url, async, user, password) {
//call original
this.realOpen (method, url, async, user, password);
myCode();
}
//ensure all XMLHttpRequests use our custom open method
XMLHttpRequest.prototype.open = myOpen ;
}
在我开始使用 GM API 之前,这一直很有效。当我将以下行添加到元部分时,我的代码会中断,并且不再调用 myOpen
:
// @grant GM_getValue
这实际上可以是任何 GM API,但我的代码会损坏。
即使使用 GM API,我的脚本中的其他所有内容也能正常工作,只是 XMLHttpRequest.prototype.open
函数的重载会中断。
我可以使用 waitForKeyElements
来解决这个问题,但是,我不喜欢它,因为它会由于使用的时间间隔而减慢浏览器的速度。
知道为什么 GM API 会破坏 XMLHttpRequest.prototype.open
调用的重载吗?
非常感谢,
彼得
最佳答案
The @grant
directive重新打开 Greasemonkey 的沙箱——它必须使用任何 GM_
函数。
prototype
覆盖只会影响脚本范围,而您希望它影响页面范围。为了解决这个问题,您需要注入(inject)覆盖。就像这样:
function overrideXhrFunctions () {
if (XMLHttpRequest.prototype) {
//New Firefox Versions
XMLHttpRequest.prototype.realOpen = XMLHttpRequest.prototype.open;
var myOpen = function(method, url, async, user, password) {
//call original
this.realOpen (method, url, async, user, password);
myCode();
}
//ensure all XMLHttpRequests use our custom open method
XMLHttpRequest.prototype.open = myOpen ;
}
}
addJS_Node (null, null, overrideXhrFunctions) {
//-- addJS_Node is a standard(ish) function
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
<小时/>
<小时/>
请注意,混合 GM_
函数和注入(inject)代码可能会变得很棘手。请参阅"How to use GM_xmlhttpRequest in Injected Code?"一种方法来做到这一点。
关于javascript - 将 @grant 添加到 GM 脚本会破坏 XMLHttpRequest.prototype.open 的过载吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16695062/