🌐 Language of this page : 中文
| English
【banana detect adblock】是一段由banana(422658476)(也就是我)编写,放在页面文件html中的“几乎”通用的adblock检测代码,它可能是至今为止唯一能够不停有效的检测并提示用户关闭正在运行的adblock扩展的检测代码,而它自身却能够不停逃避被adblock过滤掉的命运。
事实上这段代码已经被部署了好几年, 在这几年中,【banana detect adblock】在adblock的过滤代码维护者“每天”不停“测试”下,持续进行改进,从而变得越来越接近完美,越来越接近无懈可击,这么长时间的正常工作也证明了这段代码的有效性。
如果你正在烦恼: adblock屏蔽掉了网站上的google广告或者其他广告,而又没有还手之力,需要一段检测adblock的代码来扭转这个局面,那么【banana detect adblock】可能是你的不二选择。
[banana detect adblock] is a piece of "almost" universal adblock detection code written by banana(422658476) (that is me) and placed in the html of the page file. It may be the only one so far that can continuously and effectively detect and prompt the user Turn off the detection code of a running adblock extension, which itself can keep evading the fate of being filtered out by adblock.
In fact, this code has been deployed on 【软件No1 www.rjno1.com】 for several years. During these years, [banana detect adblock] has been continuously "tested" by the adblock filter code maintainer "every day". , continuous improvement, thus becoming closer and closer to perfection, closer to invulnerability, and the validity of this code is also proved by such a long time of normal work.
If you are troubled: adblock blocks google ads or other ads on the website, but there is no way to fight back, you need a piece of code to detect adblock to reverse this situation, then [banana detect adblock] may be your best choice.
浏览下方内容前可以先查看我在github上的一篇文章【把互联网标准出卖给扩展(ublock、adblock、adguard或其他扩展)的浏览器企业 | Browser companies that sell Internet standards to extensions (ublock, adblock, adguard, or others)】
选择adblock检测代码的误区:
所有在寻找adblock检测代码的人通常都希望:找到一段别人写的完美代码,复制,粘贴到自己网站上,从而可以永远的检测到adblock,而这段完美的代码自身又能永远都是有效的。
现实是:这是不可能的。你要知道,你想要使用一段通用代码去检测一个专门用来过滤通用代码的扩展,这本身就是一个非常可笑的想法,这就像是用一块肉去检测吃肉的老虎究竟吃不吃肉,还想着检测过后这块肉下次还能继续用,现实肯定是这块肉第一次被扔在老虎面前时就被老虎吃掉了,根本就没有下一次。
banana:所以,你怎么会有这么愚蠢的想法?
你:照这么说,你一开始就在证明你比我聪明喽。
banana:当然不是,我想说的是,我比你早好几年就有这个想法了,我比你蠢的早太多。XD 😜
所以你必须要使用一段运行逻辑基本完全相同(框架相同),但每个人使用的时候展现出来的实际代码又各有不同的代码来实现这个目标,这就是【banana detect adblock】,这也就是为什么这是一段“几乎”通用的adblock检测代码的原因,它能够使用“有些”不同的代码来避免自己的特征被识别,也能够使用“有些”不同的代码来让adblock的过滤代码维护者疲于奔命,但结果却是:你总是“临时”比他们更胜一筹。
不是编写代码的能力,不是你掌握相关知识的多寡,而是 【心态】 ,这也是为什么这段话要写在开头的原因。
【banana detect adblock】只能让你“临时”胜过adblock,但这个“临时”不是偶尔,而是永远“临时”胜过adblock,这就意味着需要你自己一直对这段代码中不通用的小部分代码进行修改,从而让它维持正常运行并占有优势,当理解整个运行原理,并熟练之后,这个修改是非常简单的,你需要做的只是适当的勤奋(不要过于勤奋,因为扩展本身通常每隔1天以上的时间(实际上大部分规则默认是4天)才自动更新一次规则)。
反过来说,之前你只能被adblock打得无法换手,现在你可以和它势均力敌并且占有一些优势,这本身就是可贵的,因为之前这可能都无法想象的。
这时你的【心态】就会出现问题:一直老是修改岂不是很繁琐,我好累,我好像永远都战胜不了adblock。
这些心态其实都是完全错误的,甚至恰恰相反,这些思想在adblock的过滤代码维护者的大脑中比你严重很多倍,为什么这么说:
adblock是一个浏览器扩展,也就是一个程序,程序必须要按照设计者给予的功能保持“自动”运行并获得想要的结果,这才能称之为一个有效的程序,如果这个自动程序在运行过程中需要人工手动进行修正才能维持正常功能和想要的结果,那么说明这个程序开始变的无效了,之所以要把一种功能通过计算机代码自动实现就是为了实现自动化,节省大量的人力,但现在必须要增加人手,进行手动维护,这本身就是本末倒置,违反了设计这个程序的目的。当需要使用的额外人力较少时,程序的无能还不会表现出来,但需要的人力数量成倍增长到不现实的情况时,程序的无能不管从使用者还是设计者、维护者方面都会表现出来,最终结果会让这个扩展使用者越来越少(扩展根本就没有效果为什么还要下载安装?),这也就达到了最终目的。
所以adblock不是被用户关闭而临时“死亡”,而是要让它因为需要大量人员进行手动维护,疲于奔命,最终因为人手严重不够,效果变差,没有人使用而真正的彻底死亡。
整个过程中,维护者还会因为精神和精力不断的被消耗和遭受打击,导致心态崩溃和退出,从而又“主动”减少这些维护者。
如何让adblock需要维护的人力成倍增长?
让更多的网站使用【banana detect adblock】或者类似的有效代码。
这样可以让维护者来拜访你,从而浪费1个或者多个维护者的时间和精力,拜访的次数越多,每次拜访花费的时间越多,效果也好,越多的人使用有效的稍有不同的检测代码,就需要越多的维护者进行针对性的手动维护,很容易产生“负载”问题和精神压力问题,从而需要的维护者数量需要指数级增长。
这个时候就可以看下敌我双方在人数方面的差异了,你的心态也能变为乐观了:
我方:每个使用检测代码的人仅需要维护一段代码,你面对的也只有1-3个左右的维护者(当然数量方面越多越好,以一敌百的爽快感是最终理想),和几小段自定义规则。
敌方:一个维护者之前可能只需要每天为3个网站手动添加额外的规则,当越来越多的网站使用【banana detect adblock】,明天需要手动改变规则的网站可能变成了5个,1年后如果变成需要每天手动维护100个网站的规则会怎么样?
使用【banana detect adblock】或者这种变化发生后,你和adblock的角色也会发生完全的改变:
之前:
你是受害者,adblock是施害者。
之后:
你是施暴者,adblock的维护者是受虐者,并且非常享受。
为什么不是角色互换,不是仅仅变成:你是施害者,adblock是受害者?
因为通常情况下,如果你打不过对方,被打一次后下次你就会避开对方,就像你无法战胜adblock时,你就会放弃和远离它。
但当你可以一直有效的检测到adblock时,adblock的维护者不能放弃必须要来解决这个问题,这就产生了微妙的变化,打个比方就是:
你打了adblock的维护者一拳,adblock的维护者也打了你一拳,但是他打你的时候你躲开了,或者你只是被碰了一下。
通常情况下,对方知道打不过你,那么明天就不会来找你了,更不会主动来找你了。
但是第二天adblock的维护者主动带着一块盾牌又来和你打架,你轻松拿掉了他的盾牌并打了他一拳,他依旧也打你一拳,你依旧躲开或者只是被碰了一下。
第三天:和第二天一样的情况和结果
。
。
。
第30天:还是和第二天一样的情况和结果。
你是不是突然发现哪边有些不对劲。。。。。是的。。。有些人好像从行为学上来说是个:那啥?
。。。哦。。。。我明白了。。。。唉。。。。我自己怎么突然变成了。。。。。
你的心态是不是从乐观开始走向有些变态了?哈哈哈,今后你会越来越享受这个过程,adblock维护者也是,这叫双赢(你赢2次)。赠人玫瑰,手有余香,何乐而不为?
当然我们作为正常人,心态当然不能这么邪恶,只能称这种行为叫做:逗你玩。
你:我活了这么久,从来没有见过像你们这种人!!
banana:你见的市面太少了,我就见过:
我是跟着乡民进来看热闹的。。。我又跳出来了我又站回去了,怎么样怎么样怎么样,我又跳出来了来打我啊笨蛋
一顿爆揍过后,像这种要求我这辈子都没见过。
有画面了吗?
1.代码写的越烂越好。
你知道你写了什么,但是对方也想要知道你写了什么,那么他必须要阅读你的代码,这时必须你读得懂而他不容易读懂,所以代码当然越烂越好(代码再烂也是你自己写的,自己天生能读懂),所以【banana detect adblock】更加适合初学者,而不是什么都懂的人。
理想的方式是你什么都不会,边学边用,并且一开始就不是所有代码必须全部理解和使用,而是更加希望你每次只用一小块你能理解并能见效的代码,如果通过几十个步骤之后才把所有代码添加到自己的网站上,这再好不过,步骤越多维护者拜访你的次数也就越多,请记住这才是你的最终目的,不要陷入我要使用一段完美代码来搞定这些维护者这个困局。而是只要当前代码能够生效就不改动。
如果你什么都明白:你就开始需要装的像个初学者一样,作出一样的行为。因为当你一次性添加了所有代码,那么整个过程只能引来维护者一次,从而浪费了不断添加代码可以产生的额外拜访次数。
2.人为故意使用不完美的代码。
如果【行为a】可以解决目前的问题,【行为a+行为b】可以更好的解决目前的问题,【行为a+行为b+行为c】可以完美解决目前的问题,你应该如何操作?
通常情况下所有人的反应应该是:直接进行【行为a+行为b+行为c】,从而根本解决目前的问题。
但在这边,你需要把【行为a+行为b+行为c】分成三次执行,因为这样可以让维护者拜访你三次而不是一次。记住,增加他的拜访次数才是你的最终目的。
1.所有代码的运行逻辑、过程和原理。
2.让你真正理解为什么这些代码通过这样的写法可以永远都不会失效,你就会有充足的使用信心,也就是一个好的【心态】。因为逻辑非常科学,从理论和现实都是完全能够实现的。
3.你需要改动的地方在哪些
4.目前代码中具有缺陷的部分也能自己简单修复和增强,就像banana这几年一直进行的改进一样。
当看完这些内容,你明白其中的逻辑,那么添加到你的网站中也容易很多。
在开始之前你应该先理解网页是如何运行的,扩展是如何运行的,从而找出破绽和优势。
当使用浏览器打开一个网页时,浏览器会创造2个互相隔离的空间:
一个运行和处理你的html、你的css、你的js,就是你在浏览器标签页中看到的内容。
另一个空间给启用的扩展也就是adblock使用,扩展中的js和其他东西会在这个独立空间中运行,防止和你的js在同一个环境中加载产生冲突,同时扩展可以通过浏览器获得权限查看你的html、你的css、你的js,虽然它并不能真正改动你的html、你的css、你的js(因为这种权限会导致扩展能偷取你的数据),但扩展的权限更高(就像你不能使用js真正的直接检测到adblcok扩展是否打开),所以它能阻止你的js中指定、部分、或者所有功能的运行,如果不能阻止还可以让运行故意产生错误,导致运行失败,而css的部分因为安全因素较少,所以扩展可以做到移除、添加、更改、隐藏等行为,就像你看到adblock的效果那样。
打个比方就是你在编辑一个txt文件,旁边站着老师,当你想要删除txt中某句话,但是老师不想要删除时,老师会在你想要删除的时候拿掉你的键盘和鼠标。如果你想要在txt中输入【pppp】这四个字母,但是老师不同意,那么老师给你键盘之前他会扣掉你键盘上【p】的键帽,让你无法按下去。
但是扩展也有它的局限性,你一定要好好利用这些缺陷:
1、扩展只能获取你的css的所有的初始值,如果页面加载完成之后css产生变化,那么这些值的变化它是获取不到的。
2、扩展不能读取和修改你的js变量,因为如果它能读取和修改这些值,那么扩展就可以偷取网页中的数据,造成安全问题。
当然上面2条可能有些错误,你可以自己通过搜索引擎获取最正确的答案。
对于css,由于扩展只能获取初始值,所以他的规则只能预测你的css属性是什么,当初始值匹配时才能忽略,隐藏,添加额外属性进行覆盖。
那css中不依靠js,只使用css能修改初始值吗?
这个应该是可以,并且目前banana只发现一个css属性能够获得这种效果,那就是css的animation(动画),动画css的from和to中的css属性不被算为css的预设值,因为这些属性虽然和其他css一样预先被加载,但是动画是等所有css 预设值生效完毕之后才运行的,所以动画中设置的css属性可以躲避adblock的规则,这个缺陷在【banana detect adblock】中使用的动画css中有使用。
扩展不能读取和修改你的js变量,那这样就万无一失了?
不用担心,不管事实是什么,【banana detect adblock】中的所有js变量和其他一样会产生特征的东西一样都被随机化了,你不需要考虑这个。
当你了解adblock的功能缺陷和他能产生的效果后,你就可以开始学习【banana detect adblock】的原理了。
1、禁止加载和生效:外联css、内联css、外联js、内联js。
2、只允许加载和生效:外联css。
3、只允许加载和生效:外联css、内联css。
4、只允许加载和生效:外联css、内联css、外联js。
5、加载和生效:外联css、内联css、外联js、内联js。
第1种情况是最为严重的,这时浏览器只能渲染html,整个网页看起来就像是个txt文本一样。
第2种情况下网页可以加载css文件,但是html中写的css内容无效,如果想要修改css效果只能修改加载的css文件。
第3种情况浏览器只能使用html和css,禁止使用一切js,这样你就不能使用js来检测adblock了。
第4种情况浏览器能使用html和css,可以加载js文件,这时如果你想要使用js来检测adblock,js代码只能写在js文件中,这也是没有什么用的,adblock最擅长阻止载入个别js文件。
第5种情况下你可以正常使用html,css,js。这也是我们最满意的检测环境。
所有的教程就是教你如何使用几个简单的不可被adblock阻止的小技巧从adblock手中夺回这些失去的权限,从而强迫adblock给予你第5种情况下的运行环境(如果不给就弹出提示窗口,如果给了呢?给了也跳出提示窗口。XD)。
不过你不要以为第5种情况下你可以运行所有的js功能,adblock可以:
1.禁止使用if
2.禁止使用settimeout
3.禁止使用function
4.允许你使用document.getElementById读取信息,但是使用document.getElementById或者类似功能对当前html或者css的值进行修改时,故意使这个功能崩溃,从而让实际操作失败。
5.其他。
当获取第5种情况的运行环境后,通过简单的方式就可以帮你夺回js中的if、settimeout、function等功能的使用权,当然还有document.getElementById等功能的修改权。
所以你会发现什么:
1.所有检测adblock的代码都应该使用内联方式书写,也就是直接写在html中,从而防止相关文件被adblock阻止。
2.adblock的设计者、贡献者、维护者是没有任何所谓的良知的,它们为了防止广告的加载可以禁止你使用任何东西(你知道吗,adblock在使用着github的服务器资源同时又在过滤github的js),所以不要怜悯它们,更加不要幻想通过乞求就可以让他们单独给你放宽标准,这些都是不切实际的。
就像是《神雕侠侣》中的李莫愁一样,把母豹的奶给婴儿充饥,但婴儿吃完奶后,她又杀掉利用完的母豹,吃豹子肉给自己充饥一样。
你会想:不至于这样把?
当你使用【banana detect adblock】或者类似代码时自然而然能够亲身体会到。
对于敌人,只有2种方式:结束它们或者折磨它们。
既然现实是我们不能短期结束adblock,也不能结束贡献者和维护者,那么折磨他们就是仅剩的选择,就像是他们当初怎么折磨你那样,让他们生不如死,然后欲仙欲死。。。错了。。。是要死要活。
增加和浪费维护者每次拜访你的时候花费的精力和时间,让他们每天疲于奔命,不断增加他们的未完成和待办事项,不断增加他们的精神压力,通过大家的努力极大的增加需要的维护者的数量,从而导致高负载和最终的崩溃。
【banana detect adblock】的教程会使用容易理解的话解释其原理,而不是教你怎么使用有些语言,从而让所有人都能够明白它的运行逻辑。
整个教程会从第1种情况开始,第5种情况结束,这样的流程更加的简单易懂,但当你实际开始使用时,应该是完全反过来的,从第5种情况开始,第1种情况结束,因为adblock的权限会越收越紧。
所以整个教程需要顺着看一遍,懂了之后开始倒着使用。
请记住,基本没有人在开始之前都会这些,基本上所有人都是边学边用,如果你没有掌握这些知识,边学边用即可,并且代码量很少,需要的知识点很少,需要学习的时间也很少。
1.php:php主要用来生成各种随机的名字和内容,从而消除【banana detect adblock】的各种特诊。如果你不懂用法,使用gogole搜索比如:substr php。就可以在www.php.net上了解到substr是用来做什么的,它怎么用,因为官方给出了很多的例子。
2.css:如果不懂css怎么用,那么google搜索比如:animation mdn。那么就可以在最受尊敬的开源浏览器组织mozilla的网站上获取animation的解释说明、用法。
3.js:google搜索比如:settimeout mdn。那么就可以在mozilla的网站上获取settimeout的解释说明、用法。
4.web开发者工具:这个默认是集成在各个流行浏览器中的功能。在firefox中,只需要按下f12或者选择右键菜单中的【检查】,就可以开始使用它调试网页。
5.ublock:没有错,你还需要一个ublock,通过ublock的【记录器】和设置中的【规则列表】,你很容易找到你的网站收到哪些规则的影响,也容易使用它进行调试。
6.ublock规则的百科。从ublock中看到那些正在作用于网站的规则,你必须要知道这些规则时是什么意思,这时你就需要这些,百科可以从
https://github.com/gorhill/uBlock/wiki
页面获得,通常你只要看页面上【My filters pane 】【My rules pane】中的内容或者子内容就能找到。
你并不需要现在就打开它们,在教程中需要这些知识的地方,如果教程说明你还是有疑问在去寻找这些东西的答案即可。
通常的认知是我们和adblock都具有使用:html+css+js的权力,但是adblock在这三项上的权限都比你大,所以我们完全束手无策,只能任人鱼肉,如何扭转这种劣势就是【banana detect adblock】最大的作用。
你再想想你还有什么可以用的,没有错,你还可以使用php(或者类似语言),php在服务器端运行,adblock并不能屏蔽,php用来生成html、css、js,缺口正是从php的使用打开的。
这说明什么:PHP是世界上最好的语言(我喜欢看吵架😀)
通常情况下,如果你知道如何在服务器端修改正在使用的网页模板、js、css,那么自然而然知道php是如何使用的,如果不知道请使用搜索引擎。
【banana detect adblock】的代码需要在哪些地方加载,为什么要从这些地方加载:
【banana detect adblock】的代码在网页中被分为三个部分,分别放在
<html>
<head>
...
...
第1部分放在这边(Part 1 here)
</head>
<body>
第2部分放在这边(Part 2 here)
...
...
...
...
第3部分放在这边(Part 3 here)
</body>
</html>
第1部分主要用来让包裹广告代码的外层div的id产生随机化,随机化后这些div的css也需要添加在这边,因为名字和之前不同,之前的css不会产生作用了,这样也可以避免破坏原来已经写好的代码。
第2部分显示在用户能够看到的网页内容的最上方, 这边放的当然是提醒用户关闭adblock的html和css代码,因为不管是否能够使用css,这些内容都会被显示在页面最顶部。
第3部分也就是整个网页的末尾,所以检测adblock的js代码都存放在这边,如果此处已经有其他js代码,那么检测adblock的js代码请放在这些js的上方,因为当检测adblock的js代码都无法执行时,其他js代码很多也早就不能执行了。
当浏览器只能运行html时,整个网页像txt文本一样,如果想要显示关闭adblock的文字和图片,那么只能放在第2部分的最顶部,这就是上传文件中的这部分代码(一张带文字的红色图片,一段文本):
<img style="display:none" src="<?php echo get_template_directory_uri() ?>/moban-img/index.png" width="800" height="600">
<div style="width: 0px;height: 0px;overflow: hidden;visibility: hidden;" ><p>禁用广告屏蔽(ad blocker),刷新页面继续浏览</p><p>Please disable your ad blocker,refresh page to view.</p><p>请使用firefox或者基于chrome的浏览器浏览本站</p><p>Please use firefox or chrome-based browser to browse this site</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p></div>
要点:
由于这些html代码只有在css不能使用的时候才显示,所以通常能够使用css的时候只需要使用css把img div元素设置为隐藏即可,也就是上方代码中的
style="display:none"
style="width: 0px;height: 0px;overflow: hidden;visibility: hidden;"
当禁用css,那么这些style也就被禁用的,内容自然就显示出来了。
由于这种情况下adblock不可能再去过滤这些提示元素,所以通常对内容不需要进行任何处理,也不需要进行任何随机化来消除特征,添加后就不用管了。
此时,如果adblock还是一直禁用css,那么用户默认就会看到这些提示信息,因为它们一直在顶部。
聪明的adblock维护者就会开启网页使用外联css的权限,也就是页面能够加载和使用存储在.css文件中的css,也就是你可以使用以下方式加载的css
<link rel='stylesheet' href='https://www.xxx.com/xxx/themes/xxxx/style.css' type='text/css'/>
由于网页模板通常都是使用这种方式加载css,所以当你获得外联css的使用权限后,网页的样式就会变得基本正常。
夺回内联css的使用权只需要2行代码。
其中一行是内联css代码,只需要类似上传代码中的:
<style>#content{height: auto;}</style>
这行代码被写在第3部分顶部,其实位置并不重要,重要的是这行css代码是被直接写在html中的。
如果你懂css,就知道它的意思非常简单,让id为content的元素的高度变为auto。
你也会猜到另一行代码写在外联css文件中,通常是在css文件的尾部添加比如
#content{height: 300px;}
这样写可以覆盖原来的设置。这样只需要对默认css进行一点修改,并且不会造成任何破坏。
这样一来,当没有内联css的使用权时,网页中id=content的元素高度被设置为只有300px,也就是只能看到一部分,只有当能使用内联css后,才能看到全部内容。
从用户方面来看就是开启adblock并被禁用内联css时,网页显示不全,比如id=content的元素中如果包含了网页文章内容,那么文章只能看到一小段。
究竟是网页中什么元素的什么属性因为禁用内联css而造成了“故障”,完全由你自己决定,如果这个被盯上了,只需要换成其他元素即可。
故障除了高度,也可以来自文字颜色、文字背景颜色等其他东西。
比如禁用内联css时,文字和背景一样是白色的,根本无法阅读,或者背景变成和文字一样是黑色的,也导致内容无法阅读,或者宽度不够,页面变的非常窄。
从逻辑上来讲,这样人为造成的任意元素的随机故障是不可能被自动捕获的,只能人工处理,此时adblock的维护者如果不想天天来手动解决这个问题,那么只能给与你内联css的使用权。
当你可以使用内联css之后,就可以开始通过使用内联css制造自相矛盾的人为故障,并利用这个故障来夺回内联js的使用权,从现在开始,仅仅使用html和css,就可以完美的检测是否开启了adblock并提醒用户关闭,还能让adblock的维护者开始疲于奔命,是不是很惊讶。
那么如何使用html和css检测是否开启了adblock并提醒用户关闭(基本原理):
网页加载后默认就跳出提醒用户关闭ablock的界面,不管用户是否开启了adblock。
添加一行内联js代码,当这行代码能运行,那么它会发挥它的作用:修改提醒界面的css属性,从而隐藏这个界面。
这样会有什么样的后果:
如果用户开启了adblock,并且内联js功能被禁用,那么提醒界面由于无法使用js自动关闭,从而就会自动一直显示。
如果用户没有使用adblock,那么js肯定能够使用,那么界面自然被js关闭了。
这样就能逼迫adblock交出内联js的使用权,是不是非常简单。
当然这样也必然会遇到问题:
由于网页运行的基本原理,js只会在html代码加载完毕,以及所有css属性应用完毕之后才开始运行。
如果使用css展现提醒界面,用js隐藏这个界面,由于2个行为之间有明显的间隔,你将会发现提醒界面会短暂的在显示器上显示之后才被关闭,也就是一闪而过。
怎么解决这个问题:使用css的animation(动画功能)。也就是animation带有的延迟功能解决。
就像上传代码中仅有的2个css动画(在@keyframes处),就是用来解决这个问题的。
默认显示的提醒界面使用css的动画属性延迟4-5秒后才显示出来,只要内联js在在这之前就隐藏提醒界面就不会出现界面一闪而过的问题。
实际上js在css执行过后0.5秒内就能完成隐藏行为,所以4-5秒的时间是完全足够的。
这时又会出现另外一个问题,由于css动画是被写在@keyframes之后的,如果adblock屏蔽了@keyframes,那么提醒界面就不会自动展现出来,这怎么解决?
使用一开始就说的【使用内联css制造自相矛盾的人为故障】来解决,简化后也就是下方代码:
提醒界面的自动显示代码:
<style>
@keyframes gld3dnone-to-block {from {height:0%;overflow:hidden;}to {height:100%;overflow:hidden;}}
#gld3dbbb{animation-name: gld3dnone-to-block;animation-fill-mode: both;animation-delay:5726ms;}
@keyframes gld3dn-to-b {from {height:0%;overflow:hidden;}to {height:99%;overflow:hidden;}}
#gld3d{animation-name: gld3dn-to-b;animation-fill-mode: both;animation-delay:5977ms;}
</style>
<style>
#gld3d p, #gld3dbbb p{font-size:1.6rem;line-height:1.6;text-align:center;margin:2rem 0;}
#gld3d, #gld3dbbb{position: fixed;width: 100%;height:100%;background: rgba(255,255,255,.95);z-index:-950;display:block;}
#gld3d{z-index:950;}
</style>
<div id="gld3d"><p>禁用广告屏蔽(ad blocker),刷新页面继续浏览</p><p>Please disable your ad blocker,refresh page to view.</p><p>请使用firefox或者基于chrome的浏览器浏览本站</p><p>Please use firefox or chrome-based browser to browse this site</p></div>
<div id="gld3dbbb"><p>禁用广告屏蔽(ad blocker),刷新页面继续浏览</p><p>Please disable your ad blocker,refresh page to view.</p><p>请使用firefox或者基于chrome的浏览器浏览本站</p><p>Please use firefox or chrome-based browser to browse this site</p></div>
js关闭提醒界面的代码:
document.getElementById('gld3dbbb').style.display="none";
document.getElementById('gld3d').style.width="0%";
自相矛盾的人为故障写在上方2段<style></style>中,而
<div id="gld3d">和<div id="gld3dbbb">
就是2个提醒界面,提醒界面的数量由你自己决定,只要你明白原理,这些都可以自定义。
2段<style></style>分别为什么内容:
第1段style都是带有@keyframes,也就是之前所说的提醒界面css动画,也就是延迟5秒中之后才展现界面。
第2段style则是提醒界面的默认css,css执行时就会执行,大概意思就是没有延迟立刻显示提醒界面。
为什么第2段style这么写不会造成界面短暂显示在显示器上?
这个时候你就需要使用google搜索:animation mdn。然后通过mdn页面查看关键的animation-fill-mode属性的原理就能明白。
简单的说,当【animation-fill-mode: both】时,动画中的from属性在动画没有启动前就会生效,也就第2段<style></style>中相同属性在生效前就被覆盖了,例子中就是默认高度为100%被动画from中的高度为0%覆盖,也就是提醒界面默认隐藏,5秒后在显示出来。
这样就解决了界面一闪而过的问题。
那既然第2段<style></style>中相同属性根本不会生效,为什么还要写在里面?
为了产生人为的矛盾。
如果没有第2段<style></style>时,adblock如果屏蔽了@keyframes中的动画,那么提醒界面就不会显示的。
当2段<style></style>都存在时:
如果adblock禁用了所有内联css,就会倒退回【2.如何在有外联css使用权限时夺回内联css的使用权(前面所说的第2种情况下):】并产生你指定的页面显示问题。
如果adblock通过禁用@keyframes,从而禁用css动画,那么提醒界面就会因为第2段<style></style>中的属性没有被正常覆盖立刻显示出来。
如果adblcok不禁用css动画和其他内联css,但是禁用了js,那么提醒界面就会在约5秒后显示出来。
这样的逻辑是不是非常完美?这个时候你就逼迫adblock交出内联js或者内联js+外联js的使用权了。
如果此时相关的html代码或者css代码被adblock抓住了特征,隐藏了相关元素怎么办?
html的问题我们使用php来解决,代码中也给出了较为完美的方案,也就是使用php产生随机代码、更多的随机数量div、带有点随机的文字来避开。
而css的部分则使用之前说的animation(动画)的css属性不被算为css的预设值来规避,如果之前写在内联css中的某个属性被检测到,你可以尝试把这个属性移到动画css的from中,看是否可以依旧正常,或者可以在能够接受的大概正常状态下。
如果adblock抓住的css特征是无关紧要的,甚至直接删除对应的css属性代码或者随机对应的属性就能避开,你也可以故意留下没用的css属性给adblock捕捉,当他使用后在移除,从而浪费他的时间和精力。
当可以使用内联js,那么环境就变得宽松的多,是否有外联js的使用权无关紧要,因为使用js检测是否有使用外联js的能力也是检测adblock的方法。
通常情况下,你会直接像下方这么写,来使用js来关闭自动显示的提醒界面,但这是不对的。
<script type="text/javascript" language="javascript">
document.getElementById('gld3dbbb').style.display="none";
document.getElementById('gld3d').style.width="0%";
</script>
因为当你获得内联js的使用权后,adblock是带着一种乞求的态度让你运行这2行代码来隐藏提醒界面的,因为你不执行这2行代码提醒界面就会跳出来,这时我们可以利用这个弱点向adblock索取更多的资源,比如if、settimeout、或者其他js功能的使用权。
如何操作,下面是一个简单的典型例子,理解后你可以层层加码。
<script>
var gld3drjno1settimeout = false;
</script>
<script type="text/javascript" language="javascript">
setTimeout(function(){
if (typeof gld3drjno1settimeout == "undefined") {
}else{
gld3drjno1settimeout = true;
}
if (gld3drjno1settimeout) {
document.getElementById('gld3dbbb').style.display="none";
}
}, 4);
</script>
例子中只使用了一行隐藏代码,也就是如果还有其他额外资源需要索取,当不能加在这个地方时,可以尝试加在另一行隐藏代码运行的外层。
这个例子的意思非常简单,如果你看懂了,甚至是有些多此一举的,但事实真的多此一举吗?
当然不是,当必须要使用settimeout和if功能,并且满足变量为指定值后才会关闭提醒界面,这样一来你就获得了settimeout、if的使用权了,是不是非常简单。
就光这样吗?
实际上你还天生索取到了document.getElementById这个重要的js功能的正常读取权、更改权,也就是所有的使用权。
因为adblock的规则能够故意设置为这类功能向html进行更改操作时导致故意崩溃,从而导致实际操作无效。
那如果真的遇到这种情况该怎么办?
后面的教程中有说明,基本就是使用try catch、promise.catch抓取这种故意的崩溃,因为崩溃会抛出error,捕获error后就说明adblock开启了。当然这个在上传的代码中try catch、promise.catch已经被嵌套在了
document.getElementById('gld3dbbb').style.display="none";
的外层,你直接复制使用即可。
这样一来try catch、promise.catch的使用权也获得了(有些人看到这些真的是好气啊😂,这也就是前面说的层层加码,想要什么问adblock要,它必须给你)。
并且这样执行不管adblock是否开启都是能正常运行的,十分完美。
当然,除了这个自动隐藏提醒界面的js功能直接写在<script></script>中,其他js代码实现的检测功能更加建议写在window.onload中,你可以在网上查阅大量和window.onload有关的很容易就明白为什么写在这边更好。
<script>
window.onload = function(){
};
</script>
这个在上传的代码中你也可以看到,有些检测功能被执行了2次,一次在onload中,一次在没有onload,但是延迟时间更长的settimeout中,这是否多余?
没有错,这依然是不多余的,你也猜到了,onload功能很容易就被adblock禁用了,如果你不想写检测window.onload功能是否能够正常运行的代码,最笨和最容易的办法就是把相同的检测代码在没有onload的js中再写一次(延迟时间建议增加4秒或者更多),毕竟这花费的时间不到10秒钟,容易理解,还非常稳定。
请记住,越是花里胡哨的代码越是带有更多的特征值,建议使用更加简单的代码。
到此为止,【banana detect adblock】中的通用执行框架就结束了,这些也就是不变部分,剩下没有描述的就是每个人自由发挥的有些不同的部分,特征值的更改、如何检测都能灵活的自定义。
如果你想要写一个类似的更加强健的检测代码,那么这段逻辑直接照抄即可,因为当你明白我上方所有描述的逻辑和流程,你就知道这几乎是完美的、唯一的、合理的获取各种权限的途径,就算有破绽,也很容易克服和修正。就像是水永远往下流,时间无法停止,地球是圆的,海水是咸的这些真理一样,这些是不能被扩展改变的。
接下来你可以使用js和多种方式检测adblock是否开启,banana会告诉你6种完全不同的检测adblock的方法。
所有人都知道adblock最普遍使用的手段就是阻止js文件成功加载来避免广告的显示。
这也成了我们检测它的方式,因为adblock使用正则表达式来批量阻止这些js,比如谷歌广告的js,大型网站的广告js,但这有个明显的漏洞:
绝大部分正则表达式是不区分网址的,任何网址只要加载了带有特定网址、或者特定文件名的js文件,这些js文件都会被阻止,这也成了一个非常可靠和甚至完美的检测方法。
下方是2个简单的例子:
<script>
var gld3dcheckguishow = false;
</script>
<script type="text/javascript" language="javascript">
function gld3d_1jserror(){
gld3dcheckguishow = true;
document.getElementById('gld3d').style.width="101%";
document.getElementById('gld3d').style.height='103%';
}
function gld3d_1jserror(){
gld3dcheckguishow = true;
document.getElementById('gld3d').style.width="101%";
document.getElementById('gld3d').style.height='103%';
}
</script>
<script type="text/javascript" src="https://www.xxx.com/xxx/themes/xxx/xxx-js/show_ads.js?v=1422" onerror="gld3d_1jserror()"></script>
<script type="text/javascript" src="https://fex.bdstatic.com/hunter/alog/dp.min.js?v=5953" onerror="gld3d_jserror()"></script>
加载对应的js文件,当js文件加载成功,那么会进入到js文件的onload() event,并调用对应的function,但是如果加载失败就会进入例子中js的onerror() event,并调用对应的function,例子中为显示提醒界面,如果你不明白,请查阅mdn中相关的内容。
看到js文件最后的【?v=1422】了吗?v=后面的数字默认是使用php语言生成的随机数字,这样就可以避开文件的缓存,从而打开每个页面都需要强行加载一次。
我们加载了2个根本就用不到的js文件,一个js文件存在于你自己的服务器中,例子中也就是show_ads.js,实际上这个文件中什么内容都么有,就因为文件名包含ads就触发了adblock的禁止加载功能,当adblcok给这个文件添加了特例,允许它加载,它的使命就结束了,你就不要管它了,当然如果你有其他点子还能利用的话更好。
还有一个js文件,例子中也就是dp.min.js,由于adblock使用了没有指定网站的正则表达式,导致在你的网站上加载也会触发禁止加载。
通常adblock给dp.min.js添加特例,也就是在你的网站上允许它加载,就跳过了这个检测,但是你有没有发现:
你可以通过更换为不同的js链接来逃避这个特例让代码依旧生效。
它必须让维护者每隔一段时间重返你的网站手动添加一个特例才能绕过检测。
还记得前面所说的我们使用检测代码的目的吗:消耗维护者的时间和精力,这是最好的手段之一,请一直使用,因为它通常都是有效的。
那如何获取这些被adblock阻止的js文件的链接?
太简单了,启用ublock浏览经常使用的大型网站,在ublock的【记录器】界面中能跳出很多很多。
如果你比较懒怎么办?没有办法,banana已经找了几十个了,在这个【link.txt】文件中,直接复制后测试一下链接是否有效就可以用了。
但是请注意:如果你的网站是【https://】,那么引用的js文件也要是【https://】开头的,因为【https://】协议中为了安全默认禁止加载【http://】链接,详细请查看mdn
但是你会担心,如果adblock的维护者在你每添加一条不同的js文件链接后,不删除之前旧的,只新增新的,那么你能使用的js文件链接岂不是越来越少?
当然不是,adblock的维护者的这种行为产生了3个很严重的问题:
1、你能找到的js链接的数量最起码可以有几十条,只要努力寻找几百条都有,不需要担心数量的问题。
2、规则列表中只添加不删除的行为会导致仅针对你一个网站的特例就可能多达几十条,如果可以的话,几百条,这样就带来了意外收获:【把规则列表当作一个垃圾桶】。
3、当往规则列表中添加的特例越多,维护起来也越耗时间和精力,添加一条新的时,他至少先要判断这条链接之前是否已经添加。
真实历经中,这些adblock的维护者在添加了不到20条的特例后就删除了所有的特例,因为他知道这样下去没完没了,这条路是走不通的。
并且规则列表中如果只是链接规则只增不减,增加的维护时间可能只有一点点,但如果发现其他的规则也出现只增不减的现象,那么这些维护者需要花费的维护时间和精力将会出现陡然增长(还记得我们的最终目的吗),为什么:
因为adblock维护者的心态开始出现严重的问题了,他们开始不想要每天不断的经历你给他们制造的挫败感(每天给予他们一点希望,然后又当着他们的面粉碎它),他们想根治这个问题,也就是他们不带着盾牌来找你了,而是带着能找到的所有不同武器找你来决斗了,今天不是你死就是我亡,事情大条啦!
既然是决斗,也就是到了生死存亡的时候,那么知己知彼才能百战百胜,所以我们先看一下对方有多少先进的飞机大炮和各种高精尖的武器。
adblock维护者们的武器列表:一堆盾牌。
😆…………😆
没有错,他们正在犯一个你一开始就犯过的错误:想用一段完美的代码搞定对方(我都活蹦乱跳好几年了,你现在还在想怎么彻底整死我,这不是脑子有病还能是什么)。
这会产生什么问题:特例规则越多,各种规则之间会产生的冲突和矛盾也越多。
当2个规则产生矛盾时,矛盾甚至可能会触发检测,并且由于规则变得极其复杂,导致需要对检测代码的分析和调试的时间多了很多倍(而你却能一眼就看出这些规则中不符合逻辑的地方),并且他们并不能像你一样充分和简单的使用调试命令console(在下方会讲到),所以花费的时间会长很多。
所以你会发现针对每个网站的特殊规则通常都是只有简单的几条,因为只能这么写,不然就会伤敌100自损10000。
结果是什么:
不是决战紫禁之巅吗,不是生死存亡一线间吗?结果怎么又是风流盲侠站的太高,一不小心一脚踩空摔了下去……
有些人可能开始需要看心理医生了……心理医生?这个大家都熟悉:再治一个就可以买mini cooper啦。
由于谷歌广告或者其他js文件加载后会往页面中添加很多个新的js全局变量,如果js被阻止,那么这些js全局变量就会缺失。
你只需要使用类似这种代码检测是否有1个或者多个指定的全局变量,或者全局变量的值是否正确就能判断adblock是否开启
setTimeout(function(){
if (typeof google_global_correlator == "undefined") {
gld3dcheckguishow = true;
document.getElementById('gld3d').style.width="101%";
document.getElementById('gld3d').style.height='103%';
}
}, 8917);
使用浏览器自带的web开发者工具,通常按下f12,或者网页右键菜单中的【检查】就会显示界面。
以firefox为例,打开web开发者工具界面后,切换到【调试器】,点击右侧【监视表达式】旁的【+】号,输入【window】,展开下方出现的【window:Window】就可以看到当前页面的所有js全局变量了。
你可以:
1.不开启adblock,展开【window:Window】,使用鼠标按下左键并往下移动就能复制页面上所有的js全局变量到txt文本。
2.开启adblock,重复上方的操作。
比较2个txt文件的差异就能把缺少的js全局变量提取出来。
需要注意的是,建议网页加载完毕并等待几秒后才打开web开发者工具界面和查看【window:Window】,这时的数量才是最完整的。
教程上方就告诉你:adblock是没有权限读取你在html生成的各种js变量的,并且由于【banana detect adblock】使用了随机变量名,所以更加不需要考虑这个问题。
但是adblock可以伪造一个或者多个由外部js生成的全局变量,来躲过对全局变量的检测。
就像是外部js文件在文件中创建了全局变量那样,adblock可以通过往html中插入一个自己的js文件,并且在js文件中创建相同名字的全局变量来欺骗检测代码。
但这是有缺陷的,由于外部js文件加载需要一定的时间,所以它们产生的全局变量很有可能会晚一些时间才生成出来,这也是为什么我们要使用settimeout延迟检测的原因之一。
但adblock是一个本地扩展,它伪造的全局变量肯定会尽快产生,所以利用时间差就能分辨真假。
你可以通过多次检测这些全局变量来解决这个问题, 在不改变当前检测时间和检测代码的情况下,比如在内联js执行开始时就进行一次相同的检测,如果js开始执行的时候就能获得一个或者多个指定的全局变量,那么这些变量很有可能是假的。
【1】之前已经说过,adblock会使用:运行指定js功能时,让其崩溃的方式来达到功能失效的目的(ublock的wiki中也有对应的说明)。但这种方式也会抛出各种error,而我们至少可以使用2种方式来捕获这些error。
【2】如果adblock使用重定向链接到noop.js的方式来欺骗你外部js文件成功加载(这样可以使对应js文件产生的全局变量变的“正常”),实际上这种欺骗方式并不能欺骗浏览器,这种欺骗会抛出error并被捕获,我们也至少可以使用2种方式来捕获这些error,同时这些error也能在web开发者工具-控制台页面看到。
实际上如何捕获这些error最正确的做法是看mdn上和error有关的页面,而不是仅仅是下面这些例子。
并且这些所谓的错误实际上即使不捕获,在web开发者工具-控制台页面也会显示出来,error错误通常用红色表示,在测试时,你可以使用console.log('show info:',e);这种代码在控制台页面追踪和查看error的实际捕获效果。
当然,console.log('show info:',e);功能还能帮你调试其他错误,这也就是为什么上传代码中很多地方都有它的原因。
但需要注意的是:当你调试结束,一定要使用
//console.log('show info:',e);
这种方式注释掉html中所有的这个功能,让它们无法运行。因为如果你不用时依旧开启,那么adblock的维护者也能使用它们返回的信息调试你的网站,从而大大提高分析的效率。
这种方式用来检测js功能是否失效。
try {
//在此处执行某些可能会引起error的行为
} catch (e) {
if (e.name == "ReferenceError")
{
console.log('show info:',e);
}
}
这种方式用来检测js功能是否失效。
const gld3dpromise = new Promise((resolve, reject) => {
setTimeout(function(){
try {
//在此处执行某些可能会引起error的行为
} catch (e) {
reject(e)
}
}, 4);
});
gld3dpromise.catch(error => {
console.log('show info:',error);
});
如果有js文件被禁止加载,或者让指定js故意重定向到noop.js(或者其他无用的文件)企图欺骗js文件加载成功,都能使用这种方式捕获,因为这些行为都会抛出error。
window.addEventListener('error',function(event) {
console.log('show info:',event);
},true);
如果有js文件被禁止加载,或者让指定js故意重定向到noop.js(或者其他无用的文件)企图欺骗js文件加载成功,都能使用这种方式捕获,因为这些行为都会抛出error。
window.onerror = function (msg, url, lineNo, columnNo, error) {
console.log('show info:',msg+url+lineNo+columnNo+error);
return false;
};
还是那句话,这些方式最正确的用法,有哪些缺陷都应该查阅mdn。
记住:如果某些元素被adblock隐藏,那么这些元素的宽度和高度会变成0。
记住:当adblock阻止广告js加载,很多时候会导致广告外层div不会像正常加载那样撑满整个区域,而是高度变的低甚至没有。
记住:外层div如果你之前设置了有些css属性,当google广告加载后,google广告可能会自动修改这些属性。也就是说如果检测到这些css属性没有被改变,那么adblock是开启状态
setTimeout(function(){
var gld3d_home = document.getElementsByClassName("qnx8de")[0];
var gld3d_4hide = false;
if (typeof gld3d_home == 'object')
{
var gld3d_home_h = gld3d_home.offsetHeight
if (parseInt(gld3d_home_h) < parseInt(20))
{
gld3d_4hide = true;
}
if (window.getComputedStyle(gld3d_home).getPropertyValue('text-align') != "center")
{
gld3d_4hide = true;
}
}
}
当你检测到adblock,并且展现了提醒界面,那么这个提醒界面可能还是会被抓住特征并被隐藏怎么办?
看到上方例子中,如果展现提醒界面时,除了设置样式,还会设置
gld3dcheckguishow = true;
也就是使用js变量的方式告诉自己:提醒界面已经显示出来了。
之后你可以在检测的最晚时间再检测一下这个变量的值,如果变量的值和界面的显示状态不同,那么直接把提醒文本直接插入到页面重要部分,并顺便把重要部分的内容抹去。
window.onload = function(){
setTimeout(function(){
if (gld3dcheckguishow)
{
var element = document.getElementById('gld3d');
if (typeof(element) != 'undefined' && element != null)
{
//+
if (element.offsetWidth == "0" || element.offsetHeight == "0")
{
//not show
document.getElementById('content').innerHTML = "<div class=\"bg space\"><p>禁用广告屏蔽(ad blocker),刷新页面继续浏览<\/p><p>Please disable your ad blocker,refresh page to view.<\/p><p>请使用firefox或者基于chrome的浏览器浏览本站<\/p><p>Please use firefox or chrome-based browser to browse this site<\/p><\/div>";
}
}
}
}, 4800);
};
当然你也可以换成其他逻辑,比如把id=content的元素的高度重新设置为300px,让情况回到原点。
当页面加载了1个或者多个google广告,那么每个广告位中的广告都是放在各自的frame元素中的,frame元素由google广告创建,如果一个页面上有4个Google广告,那么这4个frame的id名字分别为:aswift_1,aswift_2,aswift_3,aswift_4,当然这些名字你自己在web开发者工具中就能看到并找到这些名字的规律。
所以当google广告被全部拦截或者部分拦截,导致广告不能显示,那么frame元素可能不能被正常创建,或者frame的高度不正常。
我们只需要使用这类逻辑处理:
var gld3de1 = document.getElementById('aswift_1');
if (gld3de1 == null)
{
//not have
} else {
var gld3de1w = gld3de1.offsetWidth
if (parseInt(gld3de1w) < parseInt(20))
{
//not show
}
}
通常我们只需要检测其中一个,也就是第一个即可。
上传的代码中则有完整和更加健壮的逻辑。
所有例子中,你会发现不管是变量名,还是html的元素id,甚至function的名字都使用以【gld3d】开头的名字,没有错,所有会暴露特征的地方【banana detect adblock】都使用php生成了每隔1周就会自动改变的随机文本,从而可以自动躲避adblock的特征捕获。
<style>@keyframes gld3dnone-to-block
<style>#gld3d p, #gld3dbbb p{
<div id="gld3d"><p>
var gld3drjno1settimeout = false;
function gld3d_1jserror(){
并且php代码中还可以通过小小的调整就能让这些名字立刻改变,方便调试。
或许你会觉得每隔1周改变一次随机名字不够及时,但是上传的代码中,这些随机很大一部分是通过【获取当前时间是今年的第几周+当前页面的id】生成的,所以你会发现每个网页虽然在运行相同的检测代码,但是每个网页中这些随机名字都是完全不同的。
需要注意的是:由于html中元素的id必须以26个英文字母作为开头(最正确的解释请看mdn)才会生效,所以你要避免首个字符会是数字的生成方法。
比如:你可以预料到下次adblock的维护者会使用什么样的规则来解决现在你给他们制造的问题,也就是《笑傲江湖》中风清扬所说的:料敌击先。如果你没有这个本事,就不能像令狐冲那样,一剑刺瞎n个高手。
这种预测通常都是基于你对当前逻辑的分析,并且清楚的知道自己写的代码存在什么样的弱点和漏洞。这时还是那句话,不要因为不能写出完美的逻辑而失落,我们恰恰需要的就是不完美的逻辑,还记得我们的真正目的了吗?
当你尝试预测几次,发现每次结果都和你的预测根本不同时,这该怎么办?毕竟解决问题的方式并不是一种,难道还要花费大量的脑力把所有可能都分析出来?
banana:你真笨啊。
你:那你来,我倒要看看你是怎么预测准确率高达100%的,你有这么聪明吗?
banana:我比你还笨,而且我还不想动脑子。
你:你。。。。。。。。
作为一个笨人,你知道我是怎么预测的吗?
就像考试一样,为了考100分,我没有选择认真上课,而是选择考试时在老师的眼皮子底下偷看试卷的标准答案,也就是所谓的作弊。。。哈哈哈哈哈哈
当你已经被adblock的维护者盯上,并且成了一个不能根治的顽疾后,adblock的维护者或者其他人会在github上面给这一条提交issue,然后你也可以访问这个issue的链接看他们在讨论什么,如果他们找到了暂时的解决办法,通常他们会在页面的底部向过滤列表添加新的规则,偷看这个规则,这大概率是标准答案。
使用github ublock项目提交issue的搜索功能,在未解决的问题和已经解决的问题中搜索你的网址即可。
或者直接打开ublock的控制面板-规则列表,依次点开所有的【眼睛】图标,在打开的过滤文本中搜索你的网址就能找到针对你的特殊规则,在这些特殊规则的上方通常都会带有这个issue的链接。
如果你已经熟练的使用ublock的记录器,那么在记录器中很容易定位针对你的特殊规则在哪个【眼睛】图标中,issue的链接更加好找了。