如何在我的网站上检测Adblock?

444
我希望能够检测用户在访问我的网站时是否使用广告拦截软件。如果他们正在使用,我想显示一条消息,要求他们关闭以支持该项目,就像这个网站所做的那样。
如果您进入该网站并且您的浏览器启用了某种广告拦截软件,则该网站不会显示实际广告,而是显示一个小横幅,告诉用户广告收入用于主机项目,他们应考虑关闭Adblock。
我想在我的网站上做到这一点,我正在使用adsense广告,请问我该怎么做?

2
可能是检测广告拦截软件?的重复问题。 - 416E64726577
6
寻找最新解决方案的用户,请注意,https://github.com/sitexw/BlockAdBlock 上提供了一种全面的可插拔解决方案。请查看该网址。 - yeaske
8
有些人不喜欢在网上被分析和广告轰炸。我曾访问过一些网站,它们声称广告收入是支持项目的来源,但广告密度太高了,实在是有点荒谬。 - user1945782
12
现在,越来越多的网站这样做(并滥用它,并向我们谎称他们的广告不会打扰我们,并强制我们将整个网站添加到白名单才能进入...) - 有没有任何扩展或技巧可以防止它们检测到我们使用AdBlock+?- 我不介意偶尔看到一些定向横幅广告,但是点击劫持和不断出现的全屏视频弹窗不适合我。 - BrainSlugs83
3
作为建议: 如果你能察觉到人们正在使用广告拦截器,告诉他们“停止”这样的话其实并不会对你有太多帮助,而且通常会让人们感到烦恼。我总是建议,如果你能发现他们正在使用广告拦截器,那么只需放置一些本地托管的测试广告。这些广告通常会获得更高的点击率和更高的收益,或者提供一个廉价的终身会员服务,以免费提供无广告体验,并在广告空间中做宣传。同时千万不要阻挡他们分享内容,因为这是免费的口碑营销。 - lilHar
显示剩余2条评论
48个回答

498

我的解决方案不针对任何特定的广告网络,非常轻量级。我已经在生产环境中运行了几年。AdBlock会阻止包含单词“ads”或“prebid”的所有URL。所以这就是我所做的:

我在我的网站根目录下添加了一个名为prebid-ads.js的小型js文件。

这是该文件中唯一的一行代码。更新于2022-04-26将此变量命名为其他名称,请参见下文!

var canRunAds = true;

然后在您的页面某个地方:

<html>
  <head>
    <script src="/js/prebid-ads.js"></script>
  </head>
  <body>
    <script>
      if( window.canRunAds === undefined ){
        // adblocker detected, show fallback
        showFallbackImage();
      }
    </script>
  </body>
</html>

更新 2022-04-26 uBlock Origin 加载了它们自己的 ads-prebid.js 文件,该文件撤销了本回答中描述的技巧(骄傲!),他们的文件包含以下内容:

(function() {
    'use strict';
    window.canRunAds = true;
    window.isAdBlockActive = false;
})();

作为解决方案,只需将您的canRunAds变量重命名为一些有趣的东西,比如window.adsAreWithUswindow.moneyAbovePrivacy

Ans de Nijs发现和解决。谢谢!

支持的扩展程序

像ads.js这样的文件在Chrome上至少被以下广告拦截器阻止:

  • AdBlock
  • Adblock Plus
  • Adblock Pro
  • Ghostery

不兼容:

Privacy Badger


3
请问您能提供 js/ads.js 的完整链接吗?因为我在Blogger上必须将 .js 文件上传到某个地方(例如:Google Drive),而在这种情况下链接中不包含 ads。如果您能提供文件的链接,那将非常有帮助。 - Deb
124
该文件只包含单词 “var canRunAds = true;”,因此请自行创建它。 - timing
10
有些广告拦截器好像无法屏蔽 ads.js 文件,例如我使用的 Chrome 浏览器的简易广告拦截器。 - Mgamerz
10
你可以尝试在一个被广告拦截器屏蔽的 URL 上运行 Ajax 请求。如果成功了,就没有广告拦截器;如果失败了,就有广告拦截器。 - SethWhite
3
我正在使用AdBlock Plus,之前使用“ads.js”方案效果很好,但后来他们更新了算法,导致现在“ads.js”和“prebid-ads.js”都无法正常使用。不过,“ads-prebid.js”似乎还是有效的。 - John Weisz
显示剩余24条评论

144

虽然并非直接回答,但我会将广告信息加载到页面上,而不是尝试检测它。这样广告未能加载时,广告信息也会显示。


6
用户仍然可以使用Adblock屏蔽这些已被阻止的广告通知:这是我所知道的唯一缺陷。 - Anderson Green
28
这样做可能很简单,但不是正确的方法。如果您的布局变形或广告加载缓慢,用户可能会看到与他无关的错误。还要注意,Adblock正在采取措施阻止针对ABP用户的突兀消息。如果您想要请求用户解除广告拦截,请通过一个简单易隐藏的消息来实现,该消息位于布局之外(不会将其他元素推开)。请参考启用广告拦截的 https://duckduckgo.com/?q=foo+bar 网站。 - Xeevis
1
@Xeevis -- 我在找什么?-- 我认为AdBlock+已经阻止了duckduckgo正在做的任何事情。 - BrainSlugs83

129

async function detectAdBlock() {
  let adBlockEnabled = false
  const googleAdUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'
  try {
    await fetch(new Request(googleAdUrl)).catch(_ => adBlockEnabled = true)
  } catch (e) {
    adBlockEnabled = true
  } finally {
    console.log(`AdBlock Enabled: ${adBlockEnabled}`)
  }
}
detectAdBlock()


5
为了防止故障,您可以添加testAd.style.display='absolute'并将其移出屏幕。 - Gerald
4
这是一个不错的解决方案,但对于那些受到100毫秒延迟影响的人,我建议将以下内容添加到文档正文中:<div id="detect" class="ads ad adsbox doubleclick ad-placement carbon-ads" style="background-color:red;height:300px;width:300px;position: absolute;left:0;top:0;">&nbsp;</div>(当然,在测试后应该将CSS更改为 <div id="detect" class="ads ad adsbox doubleclick ad-placement carbon-ads" style="height:1px;width:1px;position: absolute;left:-999px;top:-999px;">&nbsp;</div>)。 - godblessstrawberry
3
好的,但据我所知,"absolute" 是一个 "position" 值。 - Em Seven
2
请注意,这对于Firefox的AdBlock无效。 - Eda190
1
如果您在访问控制/CORS方面遇到问题,即使使用fetch(new Request(AdUrl), {mode: 'no-cors'})运行也足以满足此用例。 - Ali
显示剩余5条评论

106

http://thepcspy.com/read/how_to_block_adblock/

使用jQuery:

function blockAdblockUser() {
    if ($('.myTestAd').height() == 0) {
        window.location = 'http://example.com/AdblockNotice.html';
    }
}

$(document).ready(function(){
    blockAdblockUser();
});
当然,你需要为AdblockNotice.html创建一个落地页,并且.myTestAd类需要反映你实际的广告容器。但这应该能够工作。
编辑:
正如TD_Nijboer建议的那样,更好的方法是使用:hidden(或者像我下面使用的:visible)选择器,以便也检查display:none。
function blockAdblockUser() {
    if ($('.myTestAd').filter(':visible').length == 0) {
        // All are hidden, or "not visible", so:
        // Redirect, show dialog, do something...
    } else if ($('.myTestAd').filter(':hidden').length > 0) {
        // Maybe a different error if only some are hidden?
        // Redirect, show dialog, do something...
    }
}

当然,如果需要的话,这两个可以合并成一个if块。

请注意,visibility: hidden也不会被任何一个过滤条件所捕获(布局空间仍然存在,但广告不可见)。要检查这一点,可以使用另一个过滤器:

$('.myTestAd').filter(function fi(){
    return $(this).css('visibility') == 'hidden';
})

这将为您提供一个广告元素数组,它们是“不可见”的(任何大于0的问题,在理论上)。


18
在这种情况下重定向是个坏主意。如果你的广告服务出现问题,所有访问者都可能被重定向到那个页面。我还建议使用窗口加载事件而不是文档就绪事件。 - Andy E
1
更好的检测方式是使用以下代码: $('.myTestAd').is(":hidden"); 因为手册指定它还可以检测宽度/高度是否为0以及显示属性是否为none。 - Nijboer IT
7
在这种情况下进行重定向是不明智的。如果你的广告服务出现故障,所有访问者可能会被重定向到那个页面。此外,他们只需编写一个简单的脚本来打败这种反制措施。而且,你真的认为通过强硬和咄咄逼人来激励用户禁用他们的广告拦截器吗?不会的,这只会惹恼他们并让他们反感你的网站。大多数网站选择直接显示一条消息而不是变得敌对。 - Synetech
这只是用于横幅广告吗?文本和弹出广告呢? - Deb
5
请不要因为用户禁用了广告而阻止他们进入您的网站,这只会加剧广告屏蔽软件的升级。如果您友善地请求我们打开广告,我们可能会这样做;但如果您试图强制我们这样做,我们要么停止访问您的网站,要么向广告屏蔽软件报告问题并修复您的网站。这正是广告屏蔽软件存在的保护用户的行为类型。 - BrainSlugs83
显示剩余2条评论

56

大多数广告是通过JavaScript动态加载的。我只是使用了onerror事件来检测广告脚本是否能被加载。看起来有效。

用GoogleAds举例:

<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" onerror="adBlockFunction();"></script>

这也可以用于其他元素,以查看广告拦截器是否拦截了内容。如果远程元素不存在或无法访问,则此方法可能会产生错误的结果。


3
这是检查广告是否已加载的最佳方法之一。因为手动加载自己的脚本并依赖于广告拦截器来阻止它有时会失败。 - MaZZly
1
这似乎是动态加载脚本的最佳解决方案。 - Carca
1
不知道自从这篇文章写出来以后有没有什么变化,但是我无法通过STANDS Chrome插件的Fair Adblock触发onerror。 - Melchester
截至2018年3月,仍然是最好的、简单而明确的解决方案。 - Daniel Vukasovich
1
如上所述,它无法与公平广告拦截器一起使用,最好检查 offsetHeight - cieunteung

20

要检测用户是否阻止广告,你只需要在广告Javascript中找到一个函数并尝试测试它即可。无论他们使用什么方法来屏蔽广告都没关系。以下是Google Adsense广告的示例:

if(!window.hasOwnProperty('google_render_ad') || window.google_render_ad === undefined) { 
    //They're blocking ads, display your banner
}

这个方法在这里介绍:http://www.metamorphosite.com/detect-web-popup-blocker-software-adblock-spam


9
对我来说,google_render_ad现在已经未定义了,只要typeof(window.google_jobrunner)不是“对象”,就可以使用。 - Dmitrii Korotovskii
5
因为这并不是你所控制的代码,所以我认为依赖它是不好的想法,因为库的重构将导致你的脚本检测所有用户的广告拦截。 - Patrick Forget
2
如果您要检查对象的属性,请使用简单的 === undefined,而不是 typeof - Robo Robok

20

您不需要额外的HTTP请求,只需计算虚拟广告的高度即可。

顺便提一下,这里有一个完整列表,列出了广告拦截器避免渲染的元素。

window.adBlockRunning = function() {
    return (getComputedStyle(document.getElementById("detect"))["display"] == "none") ? true : false;
  }()

console.log(window.adBlockRunning);
#detect {
  height: 1px;
  width: 1px;
  position: absolute;
  left: -999em;
  top: -999em
}
<div id="detect" class="ads ad adsbox doubleclick ad-placement carbon-ads"></div>


无法在uBlock Origin(已测试2022年11月9日)中工作。控制台始终显示“false”(没有广告拦截器处于活动状态),无论uBlock Origin是否处于活动状态。 - av01d

16

我的建议是:不要这样做!

任何情况下,你把人们视为“罪犯”,都会导致他们反击。

这是我的建议。

在页面顶部放置一个小而不显眼的信息(无论是否拦截广告),其中包含文本我*非常尊重*您阻止广告的权利以及一个指向另一页/弹出窗口的链接,标题为阅读更多……

在另一个页面上,明确表示你理解这是他们的计算机,他们可以自由使用广告拦截功能。

还要以一种非责难性的方式清楚地表明,使用这些拦截器会使你难以提供优质内容(详细解释原因),虽然你希望他们不要在你的网站上使用广告拦截,但这完全取决于他们的决定。专注于关闭拦截的积极方面。

那些强烈反对广告的人会忽略这一点,但你从来没有机会说服他们。那些漠不关心的人可能会被你的呼吁所感动,因为你没有采取“让我按我的方式行事,否则我就带着我的球回家”的方式,这实在应该是五岁孩子的专属领域。

记住,没有人拿枪指着你的头强迫你把东西放到网络上。尊重你的读者/用户,你可能会发现其中很多人会予以回报。


5
看起来您正在使用广告拦截器。那很好!我们也是 :)请通过告诉您的朋友来支持X! - ADTC
1
@ADTC,这种方法也可以奏效,因为没有发送“你是坏人”的信息。相反,它认识到现实并试图与读者建立联系,这更有可能引起积极的反应。 - paxdiablo

13

只需在您的网站上添加一个小脚本:

var isAdsDisplayed = true;

文件名为adsbygoogle.js

执行以下步骤:

<script src="/js/adsbygoogle.js"></script>
<script>
if(window.isAdsDisplayed === undefined ) {
  // AdBlock is enabled. Show message or track custom data here
}
</script>

在这里找到了解决方案


13

我使用jQuery最简单的解决方案是:

$.ajax({
    url: "/scripts/advertisement.js", // this is just an empty js file
    dataType: "script"
}).fail(function () {
    // redirect or display message here
});

advertisement.js文件什么也没有。当有人使用广告拦截器时,它会失败并调用该函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接