Logging af klik

Posted by Anders Carlsen Wed, 10 Feb 2010 19:18:00 GMT

Fornyligt fjernede jeg logging af klik på en hjemmeside for dels at få hurtigere og flere sidevisninger , dels for at højne min troværdighed i forhold til Google Bot.

Min gamle strategi

Jeg brugt en teknik hvor jeg ved hjælp af onclick function return false skjulte at når folk klikkede på et link først blev send til en controller som loggede klikket i database inden det blev vidresendt til den ønskede adresse. f.eks.

<a href="http://dr.dk" onclick="window.open('/links/goto/12') ; return false; >

Selvom Google skriver i deres information til webmastere at Google Bot ikke følger javascript, kunne jeg konstatere at det gør den faktisk. Dvs. Google registerede adressen links/goto og ikke dr.dk, hvilket ikke er særligt hensigtsmæssigt. Desuden koster en omdirigering ekstra tid for brugeren og ekstra resurcer på serveren, så jeg valgte at fjerne funktionen og finde en anden strategi.

Nye klik logging strategi

Så jeg tænkte, – hvordan gør Google det?

Ind på Google med Chrome, højreklik og vælg, kontroller element(Googles svar på Firebug)

<a href="http://www.1001line.dk/" class="l" 
onmousedown="return
 clk(this.href,'','','res',
'1','&amp;sig2=Yd8YBx8q77M9QpTMyuWYcw'
,'0CBAQFjAA')"><em>Svendborg Web</em></a>

Aha, så Google bruger onmusedown event til at registrerer hvad brugeren klikker på.

Onmouse down er den event som indtræffer lige når brugeren har klikket inden onclick event indtræffer.

EventListener Jeg ønskede ikke at have onmousdown tilskrevet inline til alle mine links, så jeg skulle bruge noget eventhandling og tænkte at det må jeg kunne gøre med prototype

Så jeg fandt følgende eksempel på http://www.prototypejs.org/api/function/bindaseventlistener

EventListener

var obj = { name: 'A nice demo' };

function handler(e) {
  var tag = Event.element(e).tagName.toLowerCase();
  var data = $A(arguments);
  data.shift();
  alert(this.name + '\nClick on a ' + tag +
    '\nOther args: ' + data.join(', '));
}

Event.observe(document.body, 'click', handler.bindAsEventListener(obj, 1, 2, 3));

(Af en eller anden grund virkede det først for mig da jeg fjernede body fra document.body)

Da det først virkede fik jeg hurtigt omskrevet scriptet så det passer til mit formål.


function handler(e) {
  var tag = Event.element(e).tagName.toLowerCase();
    if(tag == "a"){
        new Ajax.Request('/link_hits/click/?id=' 
                  + Event.element(e).id + "&url=" 
                  + eval('Event.element(e).href').escapeHTML() ,
                   {method: 'get', asynchronous:true, evalScripts:true})
        }
}

Event.observe(document, 'mousedown', handler.bindAsEventListener());

For at spare på serveren ønskede jeg ikke at skrive loggen i databasen men i en logfil, som jeg så efterfølgende kan parse.

Min controller action kom til at se sådan her ud.
def click
   render :nothing => true
    logger = Logger.new("#{RAILS_ROOT}/log/hits.log", 50, 1048576)
    logger.info "#{Time.now}, #{params[:url]}, #{params[:id]}, #{request.remote_ip}" 
  end

Og sådan ser min log info ud:

# Logfile created on Wed Feb 01 15:44:28 +0100 2010 by /
Wed Feb 10 15:44:28 +0100 2010, http://1001lin.dk/, 481, 127.0.0.1
Wed Feb 10 15:48:03 +0100 2010, http://localhost:3000/links/index/217-haandvaerk_byggeri, , 127.0.0.1

Så snart kan mine webstedsbrugere igen bruge links hits siden på mit websted.

Posted in , , ,  | Tags , ,  | no comments

Comments

Comments are disabled