BizTalk Utilities CV ,   Jobs ,   Code library
 
Go to the front page to continue learning about XML or select below:

Contents

ReBlogger Contents

Previous posts in XmlSerializer

 
 
Page 3292 of 17672

Unblocking Adblock

Blogger : SitePoint Blogs
All posts : All posts by SitePoint Blogs
Category : XmlSerializer
Blogged date : 2008 Feb 05

If you’re using Firefox with the Adblock Plus extension installed … have you noticed anything different on sitepoint.com?

A couple of weeks ago I implemented a site-wide script that unblocks ads which were blocked by Adblock Plus.

See, a while ago, when the whole firefox is blocked debacle was raging, I made some hand-waving statement about how easy it would be to circumvent ad-blocking software (though of course, I wouldn’t say how). Then a little while later (not quite sure when … I was probably drunk) I lost a bet, and had to prove it. The stakes were high, and I felt a little dirty, but I’m a man of my word, so I had to do it. And as it happened, it turned into a fun and interesting challenge, with a relevant point to make …

To ad or not to ad

I’m no fan of ads myself, and I really don’t have an issue with people using ad-blocking software. I know there are some who think that blocking ads is tantamount to theft, but I think their arguments are entirely specious. Any part of the web is customisable for you — you can make sites have a high-contrast color scheme because you need that to read, or you can filter out all images because you don’t have the bandwidth to load them, or you can selectively remove particular types of content because you simply don’t want to see it. It’s all the same, and objecting to one is objecting to all of them (which is why the law would never be able to intervene — making the activity of ad-blocking illegal would make all user-modification illegal, including the use of assistive technologies, user CSS and user scripting, and other extensions).

In any case it isn’t really the ad-blocking that’s the issue, it’s business models that refuse to acknowledge human nature, and content providers who want to make money while pretending that’s not their motive. The hypochrisy of that is pretty insulting, in my view — if your content is free, make it free; if it’s not free then charge for it. But don’t make it superficially free and then try to make me feel guilty when it costs you something.

Anyway

That’s my opinion, but be that as it may, I do love to throw the odd cat among the pigeons! So I implemented the un-blocking script anyway just to throw some petrol on the debate, and remind anyone who’s forgotten of a simple truth: content control — and digital rights management in general — is an arms race, and nobody will ever win.

Here’s how it works

To begin with we need to establish that Adblock is actually running — we don’t want to run the script if it isn’t or we’ll end up duplicating all our ads. There used to be a Firefox bug that exposed information about installed extensions, but that’s long since fixed. So:

if(navigator.userAgent.toLowerCase().indexOf('firefox') == -1) { return; }

var self = this, tester = document.createElement('img');
document.getElementsByTagName('body').item(0).appendChild(tester);
tester.setAttribute('src', '/ads/draino.gif');
window.setTimeout(function()
{
	if(!tester || tester.style.display == 'none')
	{
		//adblock is running
	}
}, 10);

Here we’re assuming that Adblock’s filters will match a URI containing /ads, because if it does then we’ll never be able to load that image, and that’s how we know Adblock is running. One of the clever things about Adblock is the fact that it doesn’t actually remove things from the document at all — it never lets them get to the document in the first place. Adblock hooks into Firefox’s content policy API, which controls allowable content at the level of HTTP requests, which means that blocked content is never even requested. (The empty source element is also undisplayed with a dynamically-generated user stylesheet, which can’t be overriden by any styling on the document, because user stylesheets always have precedence).

Of course if the test image isn’t blocked, then the rest of the script won’t run, but given the obviousness of the target URI, it’s pretty likely that it will.

Once we’ve established that Adblock is running we can begin to look for blockable content. The script defines a subset of URI filters (similar to Adblock itself, but limited to the ads we know we’re running), and a list of elements to check (scripts, images and iframes). Each instance of a target element is tested against the filters to see if it might be blocked, and if so we remember its address.

Now we have a list of addresses, we need to be able to request that data manually, which we can do by calling a PHP script via XMLHttpRequest — the server can request data from any domain and then pass it back up to the client. However it isn’t quite that straightforward, because even XHR requests are affected by Adblock. We need to prevent our requests from being blocked, so to do that we encode the addresses so that the filters don’t pick them up. It doesn’t need to be fancy, so Rot13 encoding is quite sufficient, and we’ll end up making requests like this:

request.open('GET', 'draino.php?encuri=uggc://jjj.zlfvgr.pbz/nqf/cebzb.wf', true);

The PHP script decodes that URI and then grabs its contents using fopen() into a buffer (other approaches are possible, but this seemed like the most straightforward; note that the PHP script itself is validated to prevent injection attacks, and disallow requests that don’t come from specified hosts). Depending on what the ad code spits out, we might get JavaScript, HTML or image data in response.

If it’s HTML that would be because the original ad was an

-->
 

    Email TopXML