48

After searching Google and Stackoverflow for a few hours I could not find a solution. What I'm trying to do is detect Adblock plus and display a simple message for now.

What I want to do is detect Adblock plus without using a JavaScript file or jQuery. Most of the adblock plus detect scripts they use a file, example "show_ads.js" that is hosted on there own domain with a line it in to set it "adblock = false;"

The problem with using a JavaScript file, users can white list that JavaScript file and it will no longer detect it. What I'm looking for is a JavaScript that loads directly into the HTML that would detect if someone is using ad blocker without the use of a file.

Example Below:

<script type="text/javascript">
 // line of code that detects if using ad blocker

 if so display message
 </script>

The reason behind doing it this way no ad blocker can white list the JavaScript file on your server. Yes I know there are other methods of getting around this with NoScript addons but I already have a solution for that. I have a great idea that has never been tried and ad blockers cannot block this once I get done with it.

Any suggestions and Examples will be greatly appreciated.

ks1322
  • 33,961
  • 14
  • 109
  • 164
chillers
  • 1,447
  • 2
  • 15
  • 25
  • 2
    I open sourced my AdBlock detector. It's here: http://esd.io/blog/detecting-adblock-javascript.html – Eli Sep 29 '13 at 23:00
  • @Eli I have found not matter what they can block anti ad blockers even if you use scripts from a different domain even iframes from different domains loaded through your site. The best and only way is to have your domain redirect to a free domain that does a quick check and send the person back with a get request. The only problem with that is they would have to turn their ad blocker off cause your random domains you keep changing every few days is not white listed even if they do it on your normal domain. – chillers Sep 30 '13 at 04:56
  • @ELI Now as for you detecting ad blockers your approach will work since they won't add it to easy list as your not blocking users from accessing your site. I was looking for a anti ad blocker like anti http://antiblock.org/ that works great especially the PHP one. The only problem is, once someone reports you to easy list they will create a few rules that will bypass it. I have created the best anti adblocker but it requires users to completely turn off ad block to access the site. I yet to find a solution that easy list cannot block and still allow users to white list the domain. – chillers Sep 30 '13 at 05:00
  • 1
    @Eli - your code failed in detecting my enabled adblock. – Lajos Mészáros Sep 14 '15 at 11:09
  • @Eli, thanks for posting your code, but as of now it does not work. See the screenshot I uploaded at: https://s12.postimg.org/t4xlpr871/Capture.png – sm535 Feb 23 '17 at 17:56
  • It escapes me why anyone would want to lend help with this question. – Tanveer Badar Jun 19 '19 at 07:03

15 Answers15

76

You don't need to have a plugin to detect adblock, simply use this:

<script type="text/javascript">
    var adblock = true;
</script>
<script type="text/javascript" src="adframe.js"></script>
<script type="text/javascript">
    if(adblock) {
          //adblock is installed and enabled on this site :-D
    }
</script>

Content of adframe.js:

adblock = false;

Update: Adblock Plus blocks certain requests or hides certain elements based on patterns it already has. One of those patterns is this (in patterns.ini):

[Filter]
text=/adframe.
hitCount=843
lastHit=1456391595626

which blocks any URL that has /adframe. in it.

Update 25th august 2018

Adblock plus has changed the way it finds the list and blocks the ads. It has bunch of lists called subscriptions which are used for blocking. For example this one which is the default one:

https://easylist-downloads.adblockplus.org/easylist.txt

You can use the rules on this file to find a file name to use. For example you can use seo-ads.js

P.S for developers: For some reason I couldn't get ABP to block these files on local environment.

P.S: ABP is my favorite ad blocker :-D

undone
  • 7,857
  • 4
  • 44
  • 69
  • This relies on AdBlocks blocking `adframe.js` always, by default. – Ken Sharp Jan 21 '16 at 15:28
  • 1
    @ken Yeah, it does. But that's ABP's default behavior. You can take a look at **patterns.ini** for more patterns. – undone Mar 01 '16 at 12:11
  • This is a good partial solution. There are others. I'm testing a bunch in the wild and will share when I'm happy with them. – Ken Sharp Mar 01 '16 at 16:08
  • I've just realised I didn't use the same name. I found that ABP also blocks `advert.js` for obvious reasons, but I see you've added how to find the list. – Ken Sharp Mar 01 '16 at 16:10
  • @KenSharp There are thousands of patterns in that file, if it matches one them, it ill be blocked. ABP updates this list regularly. – undone Mar 01 '16 at 16:19
  • Okay, I have mocked up a workaround for Analytics: http://kennystechtalk.blogspot.com/2016/03/adblockanalytics.html This is more complicated than what is needed to work around ABP altogether. – Ken Sharp Mar 02 '16 at 20:57
  • As some of you may realised, this method is outdated, here is a fix: replace "adframe.js" with "dfp.js". This is because Adblock Plus seems to no longer block the adframe.js script, hope it helps :) – creed Aug 17 '20 at 00:32
19

Use my plugin "FuckAdBlock", it can very easily detect AdBlock: https://github.com/sitexw/FuckAdBlock

Example :

fuckAdBlock.on(true, function() {
    alert('AdBlock detected !');
}).on(false, function() {
    alert('AdBlock is not detected =)');
});

Example online: http://fuckadblock.sitexw.fr/

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
SiteXw
  • 588
  • 1
  • 4
  • 14
  • 25
    That is why the fork "BlockAdBlock" exists: https://github.com/sitexw/BlockAdBlock – SiteXw Aug 19 '15 at 12:00
  • @SiteXw- I don't really understand how to install the script. Does it work with plain HTML web sites? Or I need that thing called 'Bower'? – Gabriel Nov 26 '15 at 10:50
  • @FrostyFrog here is a complete example online: http://jsfiddle.net/sitexw/vz4u101w/ – SiteXw Nov 27 '15 at 12:25
  • 3
    Downvoted for link-reliant answer when the entire script could be explained in a short answer –  Jan 12 '16 at 15:46
  • I clicked your complete example online (jsfiddle), and I got "AdBlock detected: no". However I use AdBlock for Firefox. (that's it's exact name: AdBlock). It is turned on, all the settings are default (with couple of sites whitelisted, but jsfiddle is not one of them) – Dalibor Jun 06 '21 at 06:32
10

What I've seen in the field is using a background image behind the ad. If adblock isn't active, the ad will be displayed over the background-image (which makes the background-image not viewable). If adblock is active, the ad is blocked, and the user will instead see the background-image.

<div id="ad-container">
  <img src="../ad/ad.png" id="ad">
</div>

With CSS:

#ad-container {
  background-image: url( http://domain.com/pleasedonotuseadblocker.png );
  height: 200px;
  width: 200px;
}

#ad {
  height: 200px;
  width: 200px;
}
Sumurai8
  • 20,333
  • 11
  • 66
  • 100
  • I need it to be JavaScript at least, I will be adding to the code for additional options. It would be good for one site but I plan on this code to be used on multiple sites. – chillers Aug 12 '13 at 06:27
  • 4
    Raising awareness that your site uses ads to fund the site will work better than forcing ads to be shown, even if people use adblock. There are better alternatives when a site resorts to forcing you to see ads. I solely use adblock because every site everywhere uses annoying ads. I don't mind whitelisting a site I actually want to support. – Sumurai8 Aug 12 '13 at 06:42
  • at least your honest but most users don't whitelist the site. They keep returning daily. I don't care about sites that have 9+ ads and popups the deserve to be blocked. My site has two ads off to the side no being annoying but 30% of my traffic feels they should block them. – chillers Aug 12 '13 at 06:48
  • 1
    @chiller: Increase the number of ads so that for those users who love ads you can balance those who didn't. Sounds like simple math. – hakre Aug 12 '13 at 06:50
  • 2
    @hakre I'm sorry you don't make a living off ads, I believe in a free and open internet but when you got people blocking your only source if income to pay server bills etc, it's hard to just sit there. – chillers Aug 12 '13 at 06:53
  • @chiller: You don't have to be sorry at all. Also I guess the part before the *but* was rhetoric, wasn't it? Depending on your content, you can look for a sponsor btw., so if you really have some value, why not share that? – hakre Aug 12 '13 at 06:59
  • BTW, I'll chew a bit so that ad-blockers can tell sites ad-blocking is on. I think this ain't that bad so that sites can actually block users based on that. Also search engines can more easily index ad-free content then. – hakre Aug 12 '13 at 07:01
  • @hakre that's a terrible solution. If your site is sticky enough due to good content, then adding more ads will piss off your most frequent visitors (and possibly customers) to the point that they may just install an ad blocker. Disclosure: that is exactly why I installed one. – Steven Linn Dec 23 '15 at 15:39
  • 2
    Sure, I only visit sites for content, not for ads. If site owners feel in the need of advertisement, it's their choice. I opt for installing an ad-blocker and if sites moan about that, I even don't visit them any longer. Somewhere is a border crossed, mine is when sites beg you to disable the adblocker. Your mileage may vary. Advertisement is just pollution in an information society and it exploits human beings natural interest. It's anti-social and toxic behaviour. – hakre Dec 23 '15 at 22:40
  • If you wish to discuss this further, please use a chatroom instead. – Sumurai8 Dec 23 '15 at 22:49
  • I like this solution, though it didn't work at all until I spelled height correctly in the code. My site has recommendations for products at Amazon in a narrow category. The users visit specifically to see the recommendations. I have a disclaimer on each page telling the users that buying the products through the links helps support the site. My users might not know why the images are missing without this. – Bob Ray Jul 25 '16 at 06:53
6

If you want to ads to be showing, even when AdBlock is active, you'll have to understand what AdBlock is capable to do.

  1. AdBlock can block resources from loading
  2. AdBlock can hide specific elements in the DOM.

Although it is said that AdBlock can also modify CSS, I can't find any documentation on that other than hiding and collapsing elements.


So what exactly could you do to be 'smarter' than AdBlock?

You could disguise your request in a way that it will never be 'matchable' (e.g. http://domain.com/ae9a70e0a.png, where the image name will be random every time and without a common prefix). As far as I am aware, a rule in AdBlock cannot contain a regex. A rule would either match no ads, or too many resources. It would be possible to rewrite such an url on the server to point to your ad.

However, while AdBlock might not be able to block your ad from loading, it might still be able to hide it. There is no real way of going around this. There will always be a smart CSS selector that will -just- select your element. You could however add a background-image with content. This is not useful for an ad (not clickable), but might help you display an other message. Downside is that if someone decides to block that annoying background image, it will hide your content too.


As far as a script goes, you might be able to load the ad with an ajax request. I suppose (but cannot test) that it will give an error if the resource could not be loaded (because it was blocked). ($.ajax( request ).error( function() { ... } ); in jQuery or some equivalent in regular javascript). You could use that to do something else. You could include that in the document itself, instead of an external resource, to ensure it will always run (if javascript is enabled). Even then, you cannot be sure that 'whatever else you do' will ever be visibly displayed. As last resort you can make a window.alert( ... ). Assume that within 3 pages, your visitors will never come back if you use that.

An other way I can think of, is making a websocket to the server (afaik this cannot be blocked by AdBlock). On the server side you'll need to examine if the ad pages are not loaded when a certain page is loaded. This information can be sent through the socket, which can be used in your script to do 'something'. This, however, sounds crazy complicated and is a significant overhead for 'just' a script that detects AdBlock.

Sumurai8
  • 20,333
  • 11
  • 66
  • 100
  • I do appreciate your answer and not bashing me on detecting ad block, and it has helped me out. I did find a simple way to detect it, it doesn't use any links like .js or img. So the ad block cannot whitelist the link to get by. Now finding a solution to prevent whitelisting divs. Thank you! – chillers Aug 12 '13 at 08:38
  • AdBlock definitely supports regular expressions. – Ken Sharp Jan 21 '16 at 15:17
  • Keep in mind that this was written for a version 3 years ago; I believe the custom rule syntax is still somewhat limited. I can't check from here if it now has full regex support. – Sumurai8 Jan 21 '16 at 15:27
4

A simple Ajax call does the job:

var xmlhttp = new XMLHttpRequest()
xmlhttp.onreadystatechange = function() {
  if( xmlhttp.readyState == XMLHttpRequest.DONE ){
    if( xmlhttp.status !== 404 ){
        console.log("Blocking ads")
    }else{
        console.log("Not blocking ads")
    }
  }
}
xmlhttp.open("GET", "/498100ffe815d700cd838d1/ads/showad.js", true)
xmlhttp.send()

Or even better, without the HTTP overhead:

var adBlockTester = document.createElement('div');
adBlockTester.innerHTML = '&nbsp;';
adBlockTester.className = 'adsbox';
document.body.appendChild(adBlockTester);
window.setTimeout(function() {
  if( adBlockTester.offsetHeight === 0 ){
    console.log("Blocking ads")
  }else{
    console.log("Not blocking ads")
  }
  document.body.removeChild(adBlockTester);
}, 60);
Etienne Martin
  • 10,018
  • 3
  • 35
  • 47
3

The following snippet will pretty much detect all ad blockers. Requires jQuery.

(function(){
    var bait = 'http://googleads.g.doubleclick.net/pagead/gen_204?id=wfocus&gqid=advertisment&advert=ads';
      $.ajax({ url: bait, dataType: "script"})
      .fail(function () { alert('ad blocked'); })
      .abort(function () { alert('ad blocked'); });
    })();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

It's wrapped in a self-executing anonymous function so it doesn't interfere with other vars or code on the site.

The bait uses the most popular ad serving network (Google's double click) and includes a few other query params used by easylist and others.

The fail() and abort() methods are both required, but only one or the other will be invoked.

Don't put the code in adblocker.js or similar since those sort of filenames themselves get blocked from loading. Either inline it or include it in an random/arbitrary filename or combine it in your main site JS file.

insomniac
  • 11,146
  • 6
  • 44
  • 55
aleemb
  • 31,265
  • 19
  • 98
  • 114
  • This is the best approach, very similar to my own - https://stackoverflow.com/questions/4869154/how-to-detect-adblock-on-my-website/53036744#53036744 – zax Nov 18 '18 at 03:09
2

Here is the code to detect adblock. You can learn how the code works here

function detect()
{
    //create a iframe. Append the iframe to the body. And then after 100ms check if their offsetHeight, display or visibility is set such a way that user cannot see them.
    //In the URL use the words specific to advertising so that Adblock can do string matching.
    var iframe = document.createElement("iframe");
    iframe.height = "1px";
    iframe.width = "1px";
    iframe.id = "ads-text-iframe";
    iframe.src = "http://domain.com/ads.html";

    document.body.appendChild(iframe);

    setTimeout(function()
               {
                   var iframe = document.getElementById("ads-text-iframe");
                   if(iframe.style.display == "none" || iframe.style.display == "hidden" || iframe.style.visibility == "hidden" || iframe.offsetHeight == 0)
                   {
                        alert("Adblock is blocking ads on this page");
                        iframe.remove();
                   }
                   else
                   {
                        alert("Adblock is not detecting ads on this page");
                        iframe.remove();
                   }
               }, 100);
}
qnimate
  • 511
  • 3
  • 9
2

Simple javascript/jQuery detection that works nicely:

$('body').append('<div id="ad-container" style="position:absolute;"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=" id="ad"></div>');
var ad_container = $('body').children('#ad-container');
if(!ad_container.is(":visible")) {
  // Add your warning and/or adblock detection logic here.
}
ad_container.remove();
suncat100
  • 2,118
  • 1
  • 17
  • 22
2

The Smartest and easiest way I found is:

1) add this html code on somewhere in your markup probably on top.

<div id="bait" class="pub_300x250" style="color: #fff">.</div>

Usually ad blockers detect ad sizes of (pub_300x250) as mentioned in Easylist and blocked them, which is triggered by "bait".

2) then add this js code into your script file.

if (document.getElementById("bait").offsetHeight === 0) {
    // function code or alert (whatever) here.
   alert("Ad-Blocker DETECTED");
}

Our Script detects if that piece of markup is existed in present html by checking thorugh "bait" id.

This works for me with Adblock , AdBlock-Plus & uBlock Origin on every site on every browser.

Arslan Ameer
  • 1,010
  • 16
  • 30
  • If you do this you can add some css to hide it: #bait { position: absolute; left: -5px; } – Emeric Jan 26 '19 at 11:51
  • Yes you can. But as you can see there is no content inside div. So no need of that because it ill simply take blank point only. But if you are concerned with space then you can. You can hide by position absolute and left. :) – Arslan Ameer Jan 26 '19 at 11:53
  • Your color works on white's background only but not if the background change regularly & without the position absolute it can be a problem depending on the place you put the div ! – Emeric Jan 26 '19 at 12:02
  • Yup your right. Thats what i said. And yeah you can change color or background color of that div to transparent. – Arslan Ameer Jan 26 '19 at 12:20
1

In my case ADB was hiding the content even that there were no ads.. ( just because the ad word was present in many urls, because it was the post type slug.. )

But I noticed that they don't remove the content, just applying display: none to the body

So as an extra solution,

I just noticed that applying display: block !important; to de body, prevents hiding the content by Adblock plus

<body style="display: block !important;">
  <img src="url-containg-ad-ads-word.jpg" alt="you should see this anyway" >
</body> 
Ikhlak S.
  • 8,578
  • 10
  • 57
  • 77
Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378
1

For me none of the tricks worked, may something I was doing wrong. but this is a very specific way to implement for google ads.

window.onload = function() {
   if (document.getElementsByClassName('google-auto-placed').length == 0){
                // Adblock Detected
   }        
}

If you have other ad system like amazon, look for their generic class name / ids by inspecting page.

If you are planing to put this code in seperate .js file make sure file name does not have "Ad" word in it. just name it magic.js

If Google ever decides to change div name, this method would fail. but that seems unlikely.

Ojas Kale
  • 2,067
  • 2
  • 24
  • 39
0

It's an arms race, for sure, and I support anyone's right to block ads, but I also support websites that depend on ad revenue trying to convince users otherwise, or perhaps persuade them to subscribe or make a donation to make up for lost ad revenue. I don't approve of sites trying to force users to see ads, but a polite message is fine.

Anyway, right now it's worth noting that there are many adblocking extensions/plugins, and they can all have different ways of doing it, and it sometimes is different between OSes and browsers too. I've found that for my purposes right now, this jQuery selector is enough to at least see whether AdBlock or AdBlockplus is being used, cross-platform, across at least Chrome and Firefox:

if($("div[id^=google_ads_iframe_] iframe:visible").length == 0)  {
    // pop up a message or whatever
} 
steev
  • 916
  • 10
  • 24
0

Here is a simplest way to deal with it (no iframe, no jquery):

var elem = document.createElement('div');
elem.className = 'adclass';
document.body.appendChild(elem);
window.setTimeout(function () {
    var isAdblockEnabled = !(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
    if (isAdblockEnabled) {
        // Adblock is enabled
    }
}, 0);
-1

I know this is kinda old, but here's IMHO a better way to do it:
Add this to your <head> section:

<script type="text/javascript">
window.onload = function() {
var iframe = document.createElement('iframe'),
    randomDomain = Math.floor(Math.random() * (10000 - 100 + 1)) + 100,
    iframeLoaded = true;
    
iframe.src = "http://"+ randomDomain +".com/ads.html";
iframe.height = ".1px";
iframe.width = ".1px";
iframe.id = 'some-ad';
iframe.onload = function() {iframeLoaded = false;};

document.body.appendChild(iframe);

setTimeout(function() { 
    var someAd = document.getElementById('some-ad');
    if(!iframeLoaded ||
       someAd == null || 
       someAd.style.display == "none" || 
       someAd.style.display == "hidden" || 
       someAd.style.visibility == "hidden" || 
       someAd.offsetHeight == 0)
        document.getElementById('ab-message').style.display = 'block';
    someAd.remove();
}, 500);
};
</script>`<br>

Now you can use the ab-message id wherever you want to display a message to AdBlock users:

<div id="ab-message" style="display: none">Your message here!</div>

Note the inline style added to hide it originally (Of course, you can also do this from your own CSS file).
Also note that it takes 500ms, that's because it has to wait for the adblocker to do its thing or it won't work.

A little explanation of how this script works

First, it appends an iframe with a source of a randomly generated link. (It is randomly generated because some adblocks are smart, at some point, they realize a link is fake).
Then it runs multiple checks on that iframe (if it was loaded successfully or if its style was modified). If one of these tests is true, it then displays the ab-message element to adblock users.

This script works for most (if not all) ad blockers.

EXTRA

No point, really, could have just created a gist, but instead I created a Github project, but still, check it out and star it if it helped you.
abDetector: Simple vanilla JavaScript AdBlock Detector.
Enjoy.

Community
  • 1
  • 1
Nick Rameau
  • 1,258
  • 14
  • 23
  • 1
    Downvoted because this answer is blank without the link. You could try to explain outside of the link what you're doing. The answer below this one is also bad, someone needs to explain with words what you do to check which is create a bait ad, set a timeout (usually instant but yours is 500ms) and check if the bait exists. –  Jan 12 '16 at 15:46
  • 1
    Keep in mind that some of these random domains are owned domains that could potentially serve malware. – Dream Lane Feb 16 '16 at 17:56
-3

I have found one of the best scripts if you use third party ads.

antiblock.org Disclaimer I'm not affiliated with this site in anyway.

It will work for most sites and if they want to bypass it they will have to add their own filters (complicated for normal users) or contact adblock filters and have one added but they quit doing that cause the list is getting over loaded and slowing down ad block users.

chillers
  • 1,447
  • 2
  • 15
  • 25