如何检测我网站上的 Adblock?
我希望能够检测用户在访问我的网站时是否使用广告拦截软件。如果他们正在使用它,我想显示一条消息,要求他们关闭它以支持该项目,例如 这个网站可以。
如果您进入该网站并且您的浏览器启用了某种 adblock 软件,则该网站不会显示实际广告,而是会显示一个小横幅,告诉用户广告收入用于托管项目,他们应该考虑关闭 Adblock 。
我想在我的网站上执行此操作,我在其上使用 AdSense 广告,我该怎么做?
I would like to be able to detect if the user is using adblocking software when they visit my website. If they are using it, I want to display a message asking them to turn it off in order to support the project, like this website does.
If you enter to that site and your browser has some kind of adblock software enabled, then the site instead of showing the actual ads shows a little banner telling the users that the ad revenue is used for hosting the project and they should consider turning Adblock off.
I want to do that on my website, I'm using adsense ads on it, How can I do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
我的解决方案并不特定于某个广告网络,而且非常轻量级。我已经在生产中运行它几年了。 AdBlock 会阻止所有包含“ads”或“prebid”一词的网址。这就是我所做的:
我向我的 webroot 添加了一个名为
prebid-ads.js
的小 js 文件,这是该文件中唯一的代码行。 更新 2022-04-26 将此变量称为其他名称,请参见下文!
然后在您页面的某个位置:
更新 2022-04-26 uBlock Origin 加载他们自己的 ads-prebid.js,该js 可以恢复此答案中描述的技巧(自豪!),他们的文件包含以下内容
:解决方案只需将您的
canRunAds
变量重命名为有趣的名称,例如window.adsAreWithUs
或window.moneyAbovePrivacy
。Ans de Nijs 的发现和解决方法。谢谢!
支持扩展
像 ads.js 这样的文件至少会被 Chrome 上的这些广告拦截器拦截:
不适用于:
Privacy Badger
My solution is not specific to a certain ad network and is very lightweight. I've been running it in production for a few years. AdBlock blocks all URLs containing the word "ads" or "prebid". So this is what I did:
I added a small js file to my webroot with the name
prebid-ads.js
This is the only line of code in that file. Update 2022-04-26 Call this variable something else, see below!
Then somewhere in your page:
Update 2022-04-26 uBlock Origin loads their own ads-prebid.js that reverts the trick described in this answer (proud!), their file contains the following:
As a solution just rename your
canRunAds
variable to something fun, likewindow.adsAreWithUs
orwindow.moneyAbovePrivacy
.Discovery and workaround by Ans de Nijs. Thanks!
Supporting extensions
Files like ads.js are blocked by at least these adblockers on Chrome:
Does not work with:
Privacy Badger
这不是直接答案,但我会将消息放在要加载的广告后面......而不是尝试检测它,它只会在广告不加载时显示。
Not a direct answer, but I'd put the message behind the ad to be loaded... rather than trying to detect it, it'd just show up when the ad doesn't.
http://thepcspy.com/read/how_to_block_adblock/
使用 jQuery:
当然,您需要有一个登录页面AdblockNotice.html 和 .myTestAd 类需要反映您的实际广告容器。但这应该有效。
编辑
正如 TD_Nijboer 所建议的,更好的方法是使用
:hidden
(或:visible
,正如我在下面使用的那样)选择器,以便display: none
也被选中:当然,如果需要的话,这两个可以组合成一个
if
块。请注意,
visibility:hidden
也不会被两者捕获(布局空间保留在其中,但广告不可见)。要检查这一点,可以使用另一个过滤器:这将为您提供一组“不可见”的广告元素(理论上,任何大于
0
的元素都会出现问题)。http://thepcspy.com/read/how_to_block_adblock/
With jQuery:
Of course, you would need to have a landing page for AdblockNotice.html, and the .myTestAd class needs to reflect your actual ad containers. But this should work.
EDIT
As TD_Nijboer recommends, a better way is to use the
:hidden
(or:visible
, as I use below) selector so thatdisplay: none
is also checked:Of course, both of these could be combined into one
if
block if desired.Note that
visibility: hidden
will not be captured by either as well (where the layout space stays, but the ad is not visible). To check that, another filter can be used:Which will give you an array of ad elements which are "invisible" (with any being greater than
0
being a problem, in theory).大多数广告都是在 JavaScript 中动态加载的。我只是使用 onerror 事件来检测广告脚本是否可以加载。似乎有效。
GoogleAds 示例:
这也可以用于其他元素,以查看广告拦截器是否拦截了内容。如果远程元素不存在或无法访问,此方法可能会产生误报。
Most ads are dynamically loaded in javascript. I just used the onerror event to detect whether the ad script could be loaded or not. Seems to work.
Example with GoogleAds:
This can be used on other elements as well to see if an ad blocker is blocking the content. This method can produce false positives if the remote elements doesn't exist or cannot be reached.
要检测用户是否阻止了广告,您所要做的就是在广告 JavaScript 中找到一个函数并尝试对其进行测试。他们使用什么方法来屏蔽广告并不重要。 Google Adsense 广告的外观如下:
此方法概述如下: http://www.metamorphosite.com/detect-web-popup-blocker-software-adblock-spam
To detect if the user is blocking ads, all you have to do is find a function in the ad javascript and try testing for it. It doesn't matter what method they're using to block the ad. Here's what it looks like for Google Adsense ads:
This method is outlined here: http://www.metamorphosite.com/detect-web-popup-blocker-software-adblock-spam
你不需要额外的HTTP请求,你可以简单地计算一个假添加的高度。
顺便说一下,这里有一个完整列表,与广告拦截器避免呈现的元素相匹配。
You don't need an extra HTTP request , you may simply calculate the height of a fake add.
By the way, here is a full list matching the elements that adblockers avoid rendering.
我的建议是:不要这样做!
任何将人们视为“不法分子”的情况都会导致他们反击。
这是我的建议。
在页面顶部放置一条不显眼的小消息(无论广告是否被屏蔽),其中包含文本
我*完全*尊重您屏蔽广告的权利
以及指向另一个页面/弹出窗口的链接标题为阅读更多...
。在另一页上,明确表示您了解这是他们的计算机,并且他们可以自由使用广告拦截功能。
还要以非指责的方式明确表示,使用这些拦截器会使您更难提供精彩的内容(详细解释原因),而您更喜欢广告拦截不发生在您的网站上,这完全是他们的决定。关注关闭阻止的积极作用。
那些强烈反对广告的人会忽略这一点,但无论如何你都没有机会说服他们。那些漠不关心的人很可能会被你的呼吁所左右,因为你并没有做“让我随心所欲,否则我就带着我的球回家”的事情,老实说,这应该是五岁孩子的专属领域。
请记住,没有人用枪指着你的头并强迫你把你的东西放到网上。尊重你的读者/用户,你可能会发现他们中的很多人都会回报。
My advice is: don't do it!
Any scenario where you treat people as "wrongdoers" is going to result in them fighting back.
Here's my proposal.
Put a small unobtrusive message at the top of the page (regardless of whether ads are being blocked) with the text
I *totally* respect your right to block ads
and a link to another page/pop-up entitledRead more ...
.On the other page, make it clear that you understand it's their computer and they are free to use ad blocking.
Also make it clear in a non-accusatory way that the use of these blockers makes it more difficult for you to deliver great content (explaining why in detail) and that, while you'd prefer the ad blocking to not happen on your site, it's totally their decision. Focus on the positives of turning off blocking.
Those who are vehemently opposed to ads will ignore this but you never stood a chance of convincing them anyway. Those who are indifferent may well be swayed by your appeal since you're not doing the whole "let me get my way or I'll take my ball and go home" thing that honestly should be the exclusive domain of five year old children.
Remember, no-one held a gun to your head and forced you to put your stuff on the net. Treat your readership/users with respect and you'll probably find a good number of them will reciprocate.
我最简单的 jquery 解决方案是:
advertisement.js 不包含任何内容。当有人使用 adblock 时,它会失败并调用该函数。
My easiest solution with jquery is:
advertisement.js just contains nothing. When somebody uses adblock, it fails and the function gets called.
只需在您的网站上添加小脚本:
名称为 adsbygoogle.js
然后执行以下操作:
找到此解决方案 此处
Just add small script on your site:
With name adsbygoogle.js
Then do following:
Found this solution here
我知道已经有足够的答案了,但由于这个问题是在 Google 搜索“检测广告拦截”主题时出现的,因此我想提供一些见解,以防您不使用 adsense。
具体来说,通过此示例,您可以检测是否使用 Firefox Adblock 提供的默认 Adblock-list。它利用了此阻止列表中存在一个被 CSS id
#bottomAd
阻止的元素。如果我在页面中包含这样一个元素并测试它的高度,我就知道广告拦截是否处于活动状态:其余部分是通过通常的 jQuery 嫌疑人完成的:
如您所见,我正在使用
setTimeout
至少有 1 毫秒的超时时间。我已经在各种浏览器上对此进行了测试,大多数情况下,直接检查ready
中的元素总是返回 0;无论广告拦截器是否处于活动状态。我对此有两个想法:要么渲染尚未完成,要么 Adblock 尚未启动。我没有费心去进一步调查。I know there are already enough answers, but since this question comes up on Google searched for "detect adblock" at the topic, I wanted to provide some insight in case you're not using adsense.
Specifically, with this example you can detect if the default Adblock-list provided by Firefox Adblock is used. It takes advantage that in this blocklist there is an element blocked with the CSS id
#bottomAd
. If I include such an element in the page and test for it's height, I know whether adblocking is active or not:The rest is done via the usual jQuery suspect:
As can be seen, I'm using
setTimeout
with at least a timeout of 1ms. I've tested this on various browsers and most of the time, directly checking for the element inready
always returned 0; no matter whether the adblocker was active or not. I was having two ideas about this: either rendering wasn't yet done or Adblock didn't kick in yet. I didn't bother to investigate further.检查是否存在广告拦截的有效方法:
只需尝试触发Google广告的URL来检查是否启用了adblock。如果是,则运行callback_has_adblock,如果否,则运行callback_no_adblock。该解决方案会增加一个请求的成本,但至少它始终有效:
该解决方案适用于所有类型的广告,而不仅仅是 google adsense。
An efficient way to check if there is an adblock:
Simply check if there is adblock enabled by trying to trigger the URL of google ads. If yes then run the callback_has_adblock, if not then run the callback_no_adblock. This solution costs one request more but at least it always works:
This solution works for all kind of ads, not only google adsense.
安全的方法是将您的广告包裹在
内,并检查
其与 adblock plus 和 bluehell 防火墙配合使用的高度。
the safe way is to wrap your ads inside
<div>
and check the heightit work with adblock plus and bluehell firewall.
[2022 年 10 月 - uBlock Origin、Adblock Plus、Brave 浏览器]
如今,广告拦截器非常聪明,它们甚至可以通过重定向来欺骗广告服务器请求并返回虚假响应。以下是我发现的唯一好的解决方案,它甚至可以与我测试过的最好的广告拦截器扩展(如 uBlock Origin、Adblock Plus)和浏览器内广告拦截器(如 Brave、Opera)配合使用。它适用于那些阻止访问广告服务器以及欺骗广告服务器的人。 它可以与任何广告提供商合作,而不仅仅是 Google!它专门使用 Google 广告服务进行检测,因为它会被所有拦截器拦截,因此其可用性始终很高且速度很快。
最聪明的广告拦截器不会拦截,而是会重定向请求并返回虚假的“成功”响应。截至目前,Google 从未重定向该请求,因此我们可以检测重定向,从而检测拦截器。
重要提示:
您可以在任何地方使用此解决方案(
/
)以及任何时间。通过在任何带有任何广告拦截器的浏览器中点击运行代码片段,直接在此处尝试:
[October 2022 - uBlock Origin, Adblock Plus, Brave browser]
Ad blockers are very smart these days, they can even spoof ad server requests with redirects and return fake responses. Below is the only good solution I've found and it works with even the best ad blocker extensions (like uBlock Origin, Adblock Plus) and in-browser ad blockers (like Brave, Opera) that I've tested. It works with those that block access to the ad server, as well as those that spoof it. It works with any ad provider, not just Google! It uses Google ad service exclusively for detection, because it's blocked by all blockers, its availability is always high and it's fast.
The smartest ad blockers don't block, they redirect requests and return fake 'successful' responses. As of now, Google never redirects the request, so we can detect the redirect and thus the blocker.
Important:
You can use this solution anywhere (
<head>
/<body>
) and anytime. Try it here directly by hitting Run code snippet in any browser with any ad blocker:他们利用了 Google 广告代码创建一个 ID 为“iframe”的 iframe 的事实。因此,只要您的页面上还没有带有该 ID 的内容,这也适合您。
They're utilizing the fact that Google's ad code creates an iframe with the id "iframe". So as long as you don't already have something on your page with that ID, this'd work for you too.
我注意到之前的评论使用google adsense作为测试对象。有些页面不使用adsense,并且使用adsense块作为测试并不是一个好主意。因为 AdSense 屏蔽可能会损害您的 SEO。
以下是我如何通过 adblocker 简单阻止类进行检测的示例:
Html:
Jquery:
“ablockercheck”是 adblocker 阻止的 ID。因此,检查它是否可见,您就可以检测广告拦截器是否已打开。
I noticed previous comments uses google adsense as object to test. Some pages don't uses adsense, and using adsense block as test is not really a good idea. Because adsense block may harm your SEO.
Here is example how I detect by adblocker simple blocked class:
Html:
Jquery:
"ablockercheck" is an ID which adblocker blocks. So checking it if it is visible you are able to detect if adblocker is turned On.
AdBlock 似乎会阻止 AdSense(等)JavaScript 文件的加载。因此,如果您使用异步版本的 AdSense 广告,您可以检查
adsbygoogle
是否为Array
。必须在几秒钟后检查这一点,因为异步脚本是......异步的。下面是一个粗略概要:为了澄清起见,下面是 AdSense 异步广告代码的示例:
请注意,
adsbygoogle
已初始化为数组。adsbygoogle.js
库在执行时会将此数组更改为Object {push: ...}
。在一定时间后检查变量的类型可以告诉您脚本是否已加载。AdBlock seems to block the loading of AdSense (etc) JavaScript files. So, if you are using asynchronous version of AdSense ads you can check if
adsbygoogle
is anArray
. This must be checked after few seconds since the asynchronous script is... asynchronous. Here is a rough outline:To clarify, here is an example of what the AdSense asynchronous ads code looks like:
Notice that
adsbygoogle
is initialized as an Array. Theadsbygoogle.js
library changes this array intoObject {push: ...}
when it executes. Checking the type of variable after a certain time can tell you if the script was loaded.这很有效。
如果有 adBlocker,它会向您发出警报,
只需向一家知名广告公司发送一个针对所有广告拦截器(谷歌广告)的标头请求,如果该请求被阻止,则 adbloker 存在。
This one works good
if there's an adBlocker it will alert you
Simply it sends a header request to a well known ad company for all ad blockers (google ads), if the request is blocked then adbloker exists.
我在我的网站上使用的这种方法,也许你会发现它很有帮助。在我看来,这是最简单的解决方案。
AdBlocker 会阻止特定的类和 html 元素,通过在开发人员控制台中检查任何被阻止广告的这些选择器(它们都已列出),您可以看到哪些元素将始终被阻止。
例如,只需检查 stackoverflow 上的这个问题页面,您就会看到一堆被屏蔽的广告。
例如,任何具有
bottom-ad
类的元素都会被自动阻止。bottom-ad
类创建了一个非空 div 元素:$('.bottom-ad').css('display') == "none"
或者使用$('.bottom-ad').is(': visible')
如果值为
true
,则 AdBlocker 处于活动状态。This approach I use on my site, maybe you will find it helpful. In my opinion, it's the simpliest solution.
AdBlocker blocks specific classes and html elements, by inspecting these selectors of any blocked ads in developer console (they are all listed) you can see which elements will be always blocked.
E.g. just inspect this question page on stackoverflow and you will see bunch of blocked ads.
For example, any element with
bottom-ad
class is automatically blocked.bottom-ad
class:<div class="bottom-ad" style="width: 1px; height: 1px;">HI</div>
$('.bottom-ad').css('display') == "none"
or even better by using$('.bottom-ad').is(':visible')
If value is
true
, then AdBlocker is active.大多数广告拦截器会取消对
ads.js
的 HTTP 请求,并为元素设置0px
,但有时广告拦截器删除了 DOM,上面的一些答案将会失败,因为不检查元素的存在。使用 setTimeout() 是一种很好的做法,因为如果没有它,脚本就会与 adblocker 竞争。
下面的脚本将检查 dom 是否存在/已删除,并检查元素的
offsetHeight
是否存在。Most adblocker cancel HTTP request to
ads.js
and make0px
for the element but sometime adblocker removed the DOM, and some answer above will fail because not checking existence of the element.Using
setTimeout()
is good practice because without it, will make the script race with adblocker.The script below will check if dom exist/removed and check
offsetHeight
of an element if it exist.html 文件
wp-banners.js
这也显示在 https://detectadblock.com 。
html file
wp-banners.js
This is also shown on https://detectadblock.com.
尽管这个问题已经存在很久了,但我最近发现它非常有用,因此只能假设还有其他人仍在查看它。在查看此处和其他地方后,我推测间接检测广告拦截器的主要三个客户端检查是检查是否被阻止的
div
/img
、被阻止的iframes 和被阻止的资源(javascript 文件)。
也许它有点夸张或偏执,但它涵盖了仅阻止一两个选择的广告拦截系统,因此如果您只进行了一项检查,则可能不会被涵盖。
在您正在运行的页面上添加检查:(我正在使用 jQuery)
并在页面上的其他任何位置添加以下内容:
我使用了带有诱饵名称的 div 以及带有文本“Advert”和尺寸的外部托管图像由 AdSense 使用(感谢 placehold.it!)。
在
advertisement.js
中,您应该将一些内容附加到文档中,以便我们稍后检查。虽然看起来您所做的与以前相同,但您实际上是在检查正在加载的文件 (advertisement.js
) 本身,而不是输出。然后是广告拦截器检测脚本,它结合了所有内容。
当文档准备就绪(即加载标记)时,我们还将 iframe 添加到文档中。然后,当窗口加载时,即内容包括。加载图像等后,我们检查:
advertimsent.js
没有 被阻止一样。和样式:
希望这有帮助
Despite the age of this question, I recently found it very useful and therefore can only assume there are others still viewing it. After looking here and elsewhere I surmised that the main three client side checks for indirectly detecting an ad blocker were to check for blocked
div
/img
, blockediframe
s and blocked resources (javascript files).Maybe it's over the top or paranoid but it covers for ad blocking systems that block only one or two out of the selection and therefore may not have been covered had you only done the one check.
On the page your are running the checks add: (I am using jQuery)
and add the following anywhere else on the page:
I used a div with a bait name as well as an externally hosted image with the text "Advert" and in dimensions used by AdSense (thanks to placehold.it!).
In
advertisement.js
you should append something to the document which we can check for later. Although it seems like you're doing the same as before, you are actually checking for the file (advertisement.js
) itself being loaded, not the output.And then the ad blocker detection script which combines everything
When the document is ready, i.e. the markup is loaded, we add the iframe to the document also. Then, when the window is loaded, i.e. the content incl. images etc. is loaded, we check:
advertimsent.js
was not blocked.And the styles:
Hope this helps
如果使用新的 AdSense 代码,您可以进行简单的检查,而无需诉诸内容或 CSS 检查。
像平常一样将广告放置在标记中:
然后调用页面底部的 adsense 代码(注意不要使用
“async”
调用adsbygoogle.js
脚本时标记):然后在下面添加这个小代码片段:
AdSense 始终创建/设置标记
adsbygoogle.loaded
为true
当广告加载时,您可以将检查放入 setTimeout 函数中,以将检查延迟几秒钟。If using the new AdSense code, you can do an easy check, with out resorting to content or css checks.
Place your ads as normal in your markup:
Then you call the adsense code at the bottom of your page (note do not use the
"async"
flag when calling theadsbygoogle.js
script):Then add this little snippit of code below that:
AdSense always creates/sets the flag
adsbygoogle.loaded
totrue
when the ads are loaded, You could place the check in a setTimeout function to delay the check by a few seconds.上述所有答案均有效,但大多数答案不适用于 DNS 级广告拦截。
DNS 级广告拦截器(例如 pi-hole)基本上返回 NXDOMAIN(域不存在)作为广告拦截域列表(例如 telemetry.microsoft.com 在存在时将“不存在”)。
有几种方法可以避免这种情况:
方法 A:通过 IP 地址而不是域请求广告。
这种方法有点烦人,因为你必须跟踪 IP 地址。如果您的代码没有得到很好的维护或定期更新,这将会出现问题。
方法 B:阻止所有失败的请求 - 即使客户端报告 NXDOMAIN。
如果它是“合法”的 NXDOMAIN,这对用户来说会非常烦人。
All of the answers above are valid, however most will not work for DNS-level ad blocking.
DNS-level ad blockers(like pi-hole) basically return NXDOMAIN(domain does not exist) for a list of ad blocking domains (e.g. telemetry.microsoft.com will "not exist" when it does).
There are a few ways to circumvent this:
Method A: Request for ads by ip address, not domain.
This method is a bit annoying as you would have to keep track of ip addresses. This will be problematic if your code isn't well maintained or updated regularly.
Method B: Block all requests that fail- even if the client reports NXDOMAIN.
This will be very annoying for users if it is a "legitimate" NXDOMAIN.
如果您使用带有钩子的反应:
if you are using react with hooks:
如果您使用 jQuery 和 Google Adsense:
这更容易理解:如果 Google Ads 主 JavaScript 文件加载失败,AdSense 将无法工作,因此您可以使用 jQuery 的失败函数执行某些操作。
“立即加载您的添加”是当我附加“ins”对象时,例如:
在“// Google 无法加载主脚本,立即执行某些操作”中,我通常将图像放在广告的位置。
In case you use jQuery and Google Adsense:
This is easier to understand: if Google Ads main JavaScript file fails to load, AdSense won't work, so you do something using the fail function of jQuery.
The "Loads your add now" is when I append the "ins" objects, like:
And in "// Google failed to load main script, do something now" I generally put images in places of ads.
在 getbanner.cfm 文件中:
我认为这是检测广告拦截的最简单方法。
and in getbanner.cfm file:
I think it's easiest way to detect adblock.
我知道这个问题已经得到解答,但我查看了建议的示例网站,我发现他们是这样做的:
I know this is already answered, but I looked at the suggested sample site, and I see they do it like this:
无需超时和 DOM 嗅探。只需尝试从流行的广告网络加载脚本,然后查看广告拦截器是否拦截了 HTTP 请求。
No need for timeouts and DOM sniffing. Simply attempt to load a script from popular ad networks, and see if the ad blocker intercepted the HTTP request.