OpenX Blog

Openads adserving in AJAX sites

by Chris Nutting on August 3rd, 2007

I’ve been asked on a few times about the best ways to serve advertising on AJAX websites. On AJAX websites, moving around the website using the page navigation may not cause the page to reload. This can be used to create a more responsive user experience, however it adds some challenges when you want to include banner advertising.

The issue here is that since the web page isn’t always reloaded - the ads on the page won’t be refreshed either. This could mean that someone could spend an hour on your site and only ever see one ad!!! (This is the kind of thing which gives online advertisers and web publishers nightmares)

At first glance the solution seems obvious: serve the ads via AJAX as well. Unfortunately, this is not as simple as it sounds, there are some major limitations and a few technical challenges to overcome. The major limitation is that the webserver and the adserver must be on the same server and accessed by the same domain name – if you are serving a large number of clients this is simply not practical. The technical challenges include issues getting JavaScript to execute remote scripts and compatibility with the workarounds used to avoid double counting of ad impressions.

I was thinking about this and I think I’ve come up with a practical solution assuming you’re willing to accept some limitations imposed by <iframe> tags.

This solution involves creating a JS function which:

  1. gets the current <iframe> src= value

  2. replaces the random number cache-buster, and

  3. set the iframe src to the new value.

This function can then be integrated into your AJAX “readyState == 4” method (the one that deals with the server response) to update ads when new content is retrieved from the server.

Some features aren’t available for <iframe> tags so this won’t be suitable in all suituations. The main limitations being that companion positioning and “Don’t show banner again on page” features are not supported. You won’t be able to server expandable banners either.

I wrote a proof-of-concept page that show this… the following page will call a new ad every time the “Change Ad” link is clicked (it calls the JS function, it doesn’t reload the page):

<iframe id=‘bannerad’ name=‘bannerad’
src=http://ads.openads.org/delivery/afr.php?n=a8910c30&amp;zoneid=9&amp;cb=INSERT_RANDOM_NUMBER_HERE’
framespacing=‘0′ frameborder=‘no’ scrolling=‘no’ width=‘468′ height=‘60′></iframe>

<script type=‘text/javascript’ src=http://ads.openads.org/delivery/ag.php></script>

<script type=‘text/javascript’><!–
function replaceMe(id) {
// Get the iframe object
obj = document.getElementById(id);
// Replace the iframe src with it-self, but change the cache buster value
obj.src = obj.src.replace(/cb=[a-zA-Z0-9-_]+(&.*)?/, ‘cb=’+Math.floor(Math.random()*99999999999)+‘$1′);
}
–></script>

<br/><a href=‘#’ onClick=’replaceMe("bannerad")>Change Ad</a>

This may not be the only (or even the best) solution, but it should certainly provide a mechanism for all those with AJAX sites to recover all those lost impressions (and $$$).

I would love to hear if anyone finds this useful, has attacked this problem a different way or has any suggestions to improve this approach. Post a comment with your ideas or suggestions.

16 Comments »

  1. “The major limitation is that the webserver and the adserver must be on the same server ”

    This is simply not true…. The javascript that serves the ads must come from the same server as the ads but the content and the ad server can be on two different boxes. This is how all major ad networks work the javascript that you embed in your page pulls content from the ad servers computer. In fact the limitation is by domain the actual server/servername does not matter.

    You could write a seperate javascript that is hosted on the ad server that had hooks into it that could update the content or had a counter in it that would ask for a new add every so often. Better yet would be to attach a handler to some feature of your page that would force a fetch of the new banner every time this feater was used.

    Comment by tom printy — August 3, 2007 @ 7:06 pm

  2. You’re right if your talking about standard tags in a page, these have no cross-domain restrictions, however “serving the tags by AJAX” would mean making an XMLHttpRequest from your site to the adserver to get the new ad HTML.

    The XMLHttpRequest function is restricted to same-domain requests, the only way I found around this was to use a server-side script-proxy on your site which gets the ad from a remote server.

    Comment by ChrisNutting — August 4, 2007 @ 11:05 am

  3. Besides the issues of XMLHttpRequest, which has had workarounds like Chris mentioned involving a proxy, there is also the issue that many 3rd party ad tags use the document.write() function to write their advertisement to your website.

    Not only does document.write have compatibility issues with proper xhtml which would most likely be used on an ajax site, but it is also used to render content during ‘page load’ not after the page has been loaded.

    I had a bit of a play with this and wrote a script which finds all Openads script tags on your website, finds the src, changes the cache value, and adds a new script tag to the document’s body, it can even be added to the document where the original ad appeared, hiding the previous ad.

    Unfortunately, testing got messy when placing Openads tags which call 3rd party tags, because you have no knowledge of what may be in those tags, unless you have a tightly controlled adserver where you will always know the tags being used.

    Anyone looking into doing this may be interested in John Resig’s document.write declaration, but I can’t tell you whether this will be in compliance with any Network’s rules on not altering their advertisements scripts. Technically you are not altering their script, but I’m just adding this warning because I haven’t seen any feedback on whether such a script could be seen as unfriendly

    But after looking into this, you may agree that Chris’ suggestion is a rather nice & simple solution which doesn’t have too heavy of limitations.

    Comment by Arlen Coupland — August 6, 2007 @ 9:21 am

  4. What about a much simpler way to do AJAX ads. Simply put a placeholder IMG tag in the HTML and when you want to serve a new ad change the IMG and A tags attributes using the following code:

    // run on script startup
    var ad_img = ‘http://myads.com/ck.php?n=afaf7159&cb=’;
    var ad_link = ‘http://myads.com/avw.php?zoneid=4&n=afaf7159&cb=’;

    // run to refresh ad
    var cachebuster = ‘1$’+Math.round(99999999999*Math.random());
    $(’skyscraper1_img’).src = ad_img+cachebuster;
    $(’skyscraper1_link’).href = ad_link+cachebuster;

    // HTML for example

    PS. The scriptaculous library is used to access DOM elemements via the “$()” function.

    Comment by HackerCEO — January 16, 2008 @ 2:27 am

  5. That is definitely a good idea - it is only limited to banner Images, though - with iFrames you can display a wider variety of banners. However, if all you need is images - I would definitely recommend someone to use the IMG tag as you describe

    Comment by Arlen Coupland — January 16, 2008 @ 9:11 am

  6. Hi All,

    I am facing a problem in javascript using document.execCommand.

    Problem:
    i am using document.write(xmlString) for writing the xmlString into a local disk file using the command document.execCommand(’SaveAs’,false,’filename.PFT’);

    Here the problem is when iam using document.write command followed by document.execCommand the XML string which i want to write in the ‘filename.pft’ is working fine but the string is also appearing on the browser which it should not appear.

    Is there any alternate to perform this action…

    can any one who provide me the solution will be greatly appriaciated .

    From,
    Venkat.

    Comment by venkat — January 25, 2008 @ 11:22 am

  7. Hi,

    I’m afraid there might be better sites to get specific Javascript help — I personally can’t help off the top of my head

    It doesn’t seem that what you are trying to do is related to OpenX - or am I wrong? It would be interesting to know what you are trying to do if it is.

    Comment by Arlen Coupland — May 30, 2008 @ 9:57 am

  8. Hi,

    If you are reading this blog post and you are simply wanting to have an ad zone which refreshes every X seconds, this is quite easy.
    All you need is to go to the invocation page of a zone and choose iFrame. On the invocation properties, you can set a ‘refresh’ value (in seconds). Now when you place the invocation tag on your website it will refresh every X seconds.

    What Chris was describing is if you want an ad tag that updates upon certain actions/clicks within the website page.

    Comment by Arlen Coupland — May 30, 2008 @ 9:59 am

  9. Hello:

    We’re not happy about being forced to use iFrames for our AJAX ads: some of the ads were meant to use the same CSS as the rest of the page, so it was best to use JS. (The adserver isn’t on the same box as the target site, so we can’t use the local mode tag.)

    We could solve this issue by writing a new (or rewriting the existing) JS invocation code, so that it doesn’t use document.write, but rather acts as a function to which we can pass params, including the ID of the div where the ad is supposed to appear.

    This is close to what HackerCEO suggested in January, but has the advantage of being able to include more than simply images.

    So, does this exist already? Is it some sort of plugin I don’t know about?

    Comment by Alfred Ayache — October 1, 2008 @ 2:35 pm

  10. Update: In order to accomplish what we were looking to do, we captured the output of the delivery/ajs.php file, parsed it and replaced the document.write with a DOM innerHTML replacement. It’s a little funky, but it got us where we were going.

    I hope someone decides to add another invocation method which would handle this.

    In the meantime, thanks for all the hard work on this great package!!!

    Comment by Alfred Ayache — October 2, 2008 @ 9:43 pm

  11. alfred, this will fail if any third party ad loads remote javascript code that includes document.write. the problem is not to teach openx to not use document.write, that is pretty quickly accomplished. but you’re out of luck for third party advertisement code which you won’t be able to modify.

    iframe still seems to be the only (and ugly) way to go when using ajax :-(

    Comment by thomas — November 10, 2008 @ 5:13 pm

  12. Note that the Same Origin Policy currently requires the $hostname, $port and $protocol to match exactly, as opposed to just the $domain. Check out the Mozilla page https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript for the closest thing I’ve ever found to the “official word.”

    In short, don’t expect an XMLHTTPRequest from “www.foo.com” to work to something like “sub.foo.com” or even “foo.com” as none of those three are the same host name (there’s an exception noted at the link for the brave hand JavaScript coders there).

    Comment by dustin — February 27, 2009 @ 7:44 pm

  13. @dustin You could you just use the “domain” inside your js to call js files from different subdomains.

    Comment by Sergi — March 18, 2009 @ 10:55 am

  14. Is there a way to invoke a specific banner in the manner of direct selection? So that specific banners can be selected by a javascript variable e.g. value driven by a drop-down.

    Comment by Matt — April 28, 2009 @ 9:46 pm

  15. I would like to configure openx on my website,please tell me the procedure

    Comment by Kingfisher Airlines booking — August 18, 2009 @ 11:18 am

  16. I am looking to install openx on my website kingfisherairlinesbooking.info, any guidelines on that

    Comment by raman — November 4, 2009 @ 12:08 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment