Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use new Image() to do click tracking?

I'm developing a click tracking system to monitor the usage my company's product on external (customers) sites. I would like to be able to tell my customers to simply put a javascript call on any element using onclick.

My current approach is using an Image() object to create a request to my tracking server. This works fine, but I'm having some doubts as to whether or not this is safe. If I put this on a link, can I be sure that my request is being sent before the browser follows the link? My testing suggests that I cannot.

So I tried using onclick="return MyFunction()" which returns true when and only when the image has finished loading. However I cannot load the image while blocking the thread in Myfunction(), since javascript only runs on one thread. So I have to use a blocking call which blocks the request for say 500 ms which would decrease the risk of the request not being sent, but reduce performance on the site.

Another approach would be to use callbacks or the like to handle the page switch after the image has been loaded. Something like:

<a href="http://www.google.som" onclick="return MyFunction(this)">Link</a>

<script type="text/javascript">

function MyFunction(theLink)
{
var img  = new Image();
img.onload = function(){ location.href=theLink.href; }
img.src = "http://www.myserver.com/trackclick";

return false;

}

</script>

This would require that my customers implement the function as required above. Moreover, if the image for some reason does not load (if my server is down for instance) the customers site will break.

I checked Google's ga.js and it suggests that they use some sort of blocking rather than event handling and callbacks. But then again, their code is intentionally hard to understand.

My questions are:

  1. Can I be sure that a request using new Image().src in an onclick event is fired before the browser follows the link, or would I need to use a delay?

  2. Does this behaviour differ between browsers and browser versions?

  3. Is there a "best practice" way of doing click tracking that I haven't found yet?

EDIT: 4. Does anyone know how Google Analytics does it? They seem to use the onclick="MyFunction()" approach, without either return statements or callbacks.

like image 567
DukeOf1Cat Avatar asked Feb 15 '12 10:02

DukeOf1Cat


1 Answers

Following up on @Gaby's comment, you should use some way to avoid cached requests, you could use the Date object for that. You should also implement an onerror behaving the same way, so you don't break the site. The code should look something like:

function MyFunction(theLink){
   var img  = new Image();
   img.onload = img.onerror = function(){ location.href=theLink.href; }
   img.src = "http://www.myserver.com/trackclick?d=" + new Date().getTime();
   setTimeout(function{location.href=theLink.href; }, 350);
   return false;
}

This way, if your server is down, it won't record the user's click, but the site behaves normally. Adding a unique query string to the image's url will prevent cached requests.

If onload or onerror fails to execute because of browser incompatibilitie, you can also use a setTimeout to redirect the page to the desired url. that way, if none of the events fire in expected time, you have the ultimate fallback.

like image 149
André Alçada Padez Avatar answered Nov 04 '22 13:11

André Alçada Padez