我正在写一个用户脚本来阻止网站设置document.body.innerHTML
,这是网站检测到adblock的典型标志:
(function() {
'use strict';
console.log("Loading ...");
Object.defineProperty(document.body, "innerHTML", {
set: function() {
console.log("malicious activity detected");
throw "Don't try to fool my adblock!";
}
});
console.log("Test setting document.body ...");
try {
document.body.innerHTML = "";
} catch (e) {
console.log(e);
}
}) ();
以上用户脚本适用于Chrome + Tampermonkey。但是它在Firefox + Greasemonkey-4上的行为很奇怪。
控制台中的输出为:
正在加载...
测试设置document.body ...
检测到恶意活动
不要试图欺骗我的adblock!
因此,用户脚本加载成功,设置器也成功连接。但是当加载后,我在控制台中尝试:
document.body.innerHTML = ""
它只是设置innerHTML
而不会引发错误,就像尚未安装该挂钩一样。我已经尝试了所有@run-at
选项,但没有一个起作用。
OTAH,如果我在控制台中使用Object.defineProperty()
,则它将按预期工作。因此,我得出结论,Firefox不尊重用户脚本中的Object.defineProperty()
。
您也可以尝试访问以下网站:https://connectwww.com。通过在Chrome的Tampermonkey中安装上述用户脚本,可以成功拦截网站上的adblock检测。但是该用户脚本不适用于Firefox + Greasemonkey。
为什么Firefox 不不尊重用户脚本中的Object.defineProperty()
?有什么解决方法吗?
上述测试网站的某些知名用户脚本(例如anti-adblock-killer)也可以在Chrome上运行,但不能在Firefox上运行,我想这是出于相同的原因。
答案 0 :(得分:0)
@grant none
模式下,Greasemonkey 4 也会沙入脚本。 <子>(即大约唯一该的Greasemonkey 4 确实比Tampermonkey或Violentmonkey更好。)子>
所以,你的脚本设置脚本的范围/拷贝innerHTML
。
在与目标页面范围共享的Tampermonkey中,但是在Greasemonkey中,更恰当地分隔了两个范围。所以页面范围(以及默认的控制台)看不到的变化。
在这种情况下,我不认为the unsafeWindow
methods可以工作作出; 您必须注入替代代码。
下面是一个脚本,既Greasemonkey的4+和Tampermonkey作品(而且应该Violentmonkey过,但我没有测试)。它适用于Chrome和Firefox的:
// ==UserScript==
// @name _Overriding Target page functions can be tricky with GM 4
// @match *://YOUR_SERVER.COM/YOUR_PATH/*
// @grant none
// @run-at document-start
// ==/UserScript==
/* eslint-disable no-multi-spaces */
console.log("Loading ...");
function overrideIt () {
//-- Necessary check because of scope madness in TM, VM, etc.
if (document.body.innerHTML) {
Object.defineProperty (document.body, "innerHTML", {
set: function () {
var scopeStr = (typeof GM === "object" && GM.info) ? "script" : "page";
console.log (`Malicious activity detected - ${scopeStr} scope`);
throw "Don't try to fool my adblock!";
}
} );
}
}
overrideIt ();
if (typeof unsafeWindow === "object") {
console.log ("unsafeWindow detected.");
addJS_Node (null, null, overrideIt);
}
console.log ("Test setting document.body ...");
try {
document.body.innerHTML = "";
} catch (e) {
console.log ("Caught: ", e);
}
//-- 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);
}