Newsgroup: it.comp.lang.javascript
Titolo: tempo di permanenza su una pagina web

Ciao,
mi date una mano a capire la fattibilità di questa cosa?
vorrei poter registrare il tempo di permanenza su una pagina web.
al momento io posso ovviamente avere tranquillamente l'ora di arrivo 
sulla pagina.
se io impostassi una funzione (stile ajax, o meglio ahah) che mi 
richiama la pagina lato server per memorizzare il tempo di uscita 
sull'unload del body potrebbe funzionare? qualcuno ha qualche esperienza 
in tal senso?
al limite potrei lanciare la funzione su tutti i link interni al sito e 
ignorare la chiusura del browser o il cambio di dominio, in fondo 
falserebbe sì i risultati, ma non mi cambierebbe più di tanto a tutti 
gli effetti. cosa dite?
ced

 vorrei poter registrare il tempo di permanenza su una pagina web.
Beh, dato che è stateless l'unica che mi viene in mente è xmlhttprequest.
Oppure un bel frame nascosto che si ricarica ogni x secondi? Così: a) setti
un cookie con dataini b) ricarichi ogni tot e ti registri data_end
(aggiornandola ad ogni ricarica)
p.s. ho sentito voci che xp sp2 fa casini con i frame nascosti, verifica
-- 
"Affacciati affacciati benedici, guardaci
 guardaci...guardaci!
 Tanto sono quasi duemila anni che stai a guardare!"
									    E.B.

 Beh, dato che è stateless l'unica che mi viene in mente è xmlhttprequest.
era esattamente quello che avevo in mente...
diciamo che io ho trovato le funzioni in calce.
posto che userei solo la prima e che ho eliminato il target, visto che 
non devo visualizzare alcun risultato, ho comunque il problema di 
lanciarla in uscita dalla pagina...
mi spiego:
sui link nella pagina ho messo la funzione su onclick con un return true 
alla fine ed in effetti la lancia e poi va al link, purtroppo non riesco 
a lanciarla in onunload del body, quindi mi perdo tutti quelli che 
escono chiudendo il browser o digitando direttamente un url nella barra 
di navigazione... inoltre non riesco a intercettarla sui click a parti 
della pagina include (non posso mettere l'onclick anche su quelli perchè 
sono inclusi anche in pagine in cui non ho questa funzione).
ho provato a intercettare un click su qualsiasi link con una funzioncina 
ad hoc, ma non funziona, o meglio, intercetta il link, lancia la 
funzione ma la pagina del browser è già cambiata senza attendere il 
passaggio dei dati (passandomeli quindi errati).
sono stato troppo confusionario?
idee o consigli?
cedmax
var old='';
function ahah(a,target,b) {
var url= a+b;
old=b;
document.getElementById(target).style.display='block';
    // native XMLHttpRequest object
    document.getElementById(target).innerHTML = 'sending...';
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = function() {ahahDone(target);};
        req.open("GET", url, true);
        req.send(null);
    // IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = function() {ahahDone(target);};
            req.open("GET", url, true);
            req.send();
        }
    }
}
function ahahDone(target) {
    // only if req is "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            results = req.responseText;
            document.getElementById(target).innerHTML = results;
        } else {
            document.getElementById(target).innerHTML="ahah error:\n" +
                req.statusText;
        }
    }
}
//-->

 purtroppo non riesco a lanciarla in onunload del body
Premessa solita: sono niubbo.
Seconda premessa: mi sto scervellando un po' anch'io su queste cose...
Detto cio', ho provato una cosa molto simile a quella che fai tu: con una
richiesta GET non funziona, con una POST si'... mo' francamente non riesco
a spiegarmi il perche'.
Risolto questo (in modo troppo empirico e ben poco ragionato) sono venuti
fuori altri problemi che non riesco a capire... vabbe', continuo a
scervellarmi :)
-- 
Nando [?]
Ex-Apostolo della Ex-Prova

 a spiegarmi il perche'.
idea interessante, provo, grazie
ced

 idea interessante, provo, grazie
in realtŕ ho trovato:
chiamando sull'unload del body non devo mettere &amp; al posto di & 
nella stringa che passo...
non capisco perchč, ma cosě lo interpreta correttamente...
cedmax

 non capisco perchè, ma così lo interpreta correttamente...
Ah, beh, io so' gnubbo, un lo so :)
Cmq, a me funziona tutto tranne... un problemino che non riesco a
risolvere, sto cercando da 2 ore su google ma non trovo soluzioni, forse e'
un bug di mozilla... insomma, nell'handler dell'evento unload della pagina
invio una richiesta http asincrona, che giunge correttamente al server che
fa cio' che deve; mi preoccupo pure di abortire tutte le eventuali
richieste http in pendenza... il problema e' che mi da' comunque un errore:
pare che comunque parta il gestore dell'evento readystatechange, riesca a
leggere la proprieta' readyState dell'oggetto XmlHttpRequest, ma poi dia
errore quando cerca di accedere alla proprieta' status del medesimo
oggetto.
Aiuto, sto impazzendo.
Ah, per non parlare poi del fatto che non riesco a far si' che il browser
*non* riprenda la pagina dalla cache, quando si fa un reload sul client...
Aiuto.


 Aiuto, sto impazzendo.
se potessi aiutarti lo farei volentieri, purtroppo non ho a mano altre 
conoscenze se non le funzioni che ho postato... non sono esattamente uno 
sviluppatore js...
ced

 sviluppatore js...
Ah, beh, sapessi io!
Argh... ci sono stato ore... pare che funzioni tutto... aiut...
Pero' e' venuto fuori un bordello... funziona, ma chi ci capisce e' bravo
:)
Buoanotte.


 oggetto.
Scusa la domanda, ma che te ne frega di leggere la proprietŕ readyState?
L'importante č che la chiamata al server sia arrivata. Anche perché, se
putacaso vi sono stati dei problemi, non č che puoi "correggerli". Non c'č
modo di impedire l'onunload.
E poi, idealmente se io chiudo la finestra del browser, questo dovrebbe
distruggere tutte le referenze e quindi non dovrei "basarmi" su ciň che
avevo per realizzare uno script ad associare all'onunload, tanto meno per
gestire un eventuale risposta del server (poi nella tecnica ciň non č
sempre vero, c'č un tempo di "interregno", ma č abbastanza empirico e
dipende esclusivamente da come si č svegliato la mattina il team di
sviluppo che ha realizzato il browser in questione).
Premesso che questo genere di cose generalmente non le faccio, io non sarei
stato a scomodare XmlHttpRequest. Avrei semplicemente usato il vecchio
approccio dell'immagine, in virtů del fatto che ciň che conta č che la
richiesta arrivi al server, e non la risposta che giunga al client.
E ovviamente č un approccio che funzionerebbe su molti piů browser.
-- 
.ZER0//sign
"When you have eliminated the impossible, whatever remains,
however improbable, must be the truth." (S.H.)
on air ~ "Oliver Onions - Bulldozer"

 E ovviamente è un approccio che funzionerebbe su molti più browser.
Il fatto e' che non credo che il problema sia la richiesta fatta nel
gestore dell'evento unload, alla quale neanche attacco un gestore
dell'evento readystatechange.
Ti spiego meglio... per imparare qualcosa ho deciso di provare a realizzare
una chat (scopo esclusivamente autodidattico) utilizzando xmlhttprequest.
Volevo far si' che, quando l'utente lascia la pagina, venga effettuato
automaticamente il logout dalla chat. La chat l'ho realizzata con uno
scheduler delle operazioni di lettura/scrittura... vabbe', e' troppo lungo
spiegarlo qui e magari neanche ti interessa :-)
Ad ogni modo, credo siano le operazioni di richiesta (letture/scrittura)
pendenti a creare problemi, non la richiesta di logout.


 pendenti a creare problemi, non la richiesta di logout.
Premesso che non avendo visto il codice può essere di tutto; se ciò che
dici fosse vero dovresti avere lo stesso problema ancor prima di scatenare
l'evento onunload. Se il problema fosse unicamente di richieste pendenti,
intendo.
Se ciò non accade, ma è in congiunzione all'onunload è evidente che non si
tratta solo di pendenza, ma di questa con la distruzione del contesto
attuale (che avviene nel momento in cui chiudi il browser/cambi pagina).
Se nell'evento unonload non invochi un'altra richiesta al server tramite
XmlHttpRequest (per fare il logout) il problema sussiste ugualmente?
In questo modo capiresti se si tratta di qualcosa che è già rimasto appeso
da prima, oppure no.
-- 
.ZER0//sign
"When you have eliminated the impossible, whatever remains,
however improbable, must be the truth." (S.H.)
on air ~ "Fiorella Mannoia - Il cielo d'Irlanda"

 da prima, oppure no.
Provato: si', il problema sussiste. Sempre e solo su firefox.


 Provato: si', il problema sussiste. Sempre e solo su firefox.
Bene, è già qualcosa.
-- 
There is no emotion; there is peace.
There is no ignorance; there is knowledge.
There is no passion; there is serenity.
There is no death; there is the Force. (Jedi Code)

 meno.
Si'. Non persiste; inoltre, la digitazione del messaggio e' "scattosa";
infine, si verifica comunque un errore, di tipo diverso:
Errore: [Exception... "'Permesso negato per impostare la proprietà
XULElement.selectedIndex' when calling method:
[nsIAutoCompletePopup::selectedIndex]"  nsresult: "0x8057001e
(NS_ERROR_XPC_JS_THREW_STRING)"  location: "JS frame ::
http://www.miodominio.xx/chat/script/chatscript.js
 :: anonymous :: line
151"  data: no]
File sorgente:
http:/www.miodominio.xxt/chat/script/chatscript.js
Riga: 151
esattamente qui:
oXmlHttp.send(postString);
e si verifica quasi ogni volta che digito una lettera nel campo di input.
Non comprendo...
Tanto per completezza, l'errore originario, quello che ho quando uso le
richieste asincrone, e' riportato sotto; su bugzilla sono segnalate molte
bug che fanno riferimento a questo codice di errore, ma nessuna che si
verifichi in casi uguali al mio; inoltre, sottolineo che l'errore si
verifica in circostanze particolari, ad es.:
1) appena entro in chat faccio *immediatamente* il refresh della pagina
2) ricarico la pagina *immediatamente dopo* aver inviato un messaggio alla
chat
E ricordo che il refresh della pagina comporta il logout dalla chat.
Durante il funzionamento normale, non si verifica alcun errore.
Aiuto (O)___(O)
Errore: [Exception... "Component returned failure code: 0x80040111
(NS_ERROR_NOT_AVAILABLE) [nsIXMLHttpRequest.status]"  nsresult: "0x80040111
(NS_ERROR_NOT_AVAILABLE)"  location: "JS frame ::
http://www.miodominio.xx/chat/script/chatscript.js
 :: anonymous :: line
607"  data: no]
File sorgente:
http://www.miodominio.xx/chat/script/chatscript.js
Riga: 607
La riga incriminata e':
if (oXmlHttp.status && !isNaN(oXmlHttp.status) && oXmlHttp.status == 200) {
NB le prime due condizioni nell'if le ho inserite per disperazione per
vedere se cambiava qualcosa ma, credo, sono inutili.


 Non comprendo...
E' probabilmente il discorso dell'autocomplete, è un bug di firefox noto. Ne è
stato fatto qualche accenno anche nel NG.
Prova a impostarlo ad off:
<input type="text" name="yourtext" autocomplete="off" /> 


 <input type="text" name="yourtext" autocomplete="off" />
Altra cosa ignota. Grazie mille per la dritta.
Ah... posso settarlo con setAttribute("autocomplete","off") oppure ci sono
problemi anche con questo?
Cmq, quando avro' ristrutturato il tutto per benino, ti faro' sapere... se
ti interessa, chiaramente!
Ciao e buon anno.


 problemi anche con questo?
Prova. Non credo vi siano problemi di sorta, ma essendo un bug non c'è la
certezza.


 certezza.
Ribadisco che il problema imputabile al bug nell'autocompletamento si
verifica solo se uso chiamate sincrone. E' normale?


 verifica solo se uso chiamate sincrone. 
Non ho capito: vuoi dire che con autocomplete="off" non lo risolvi?


 Non ho capito: vuoi dire che con autocomplete="off" non lo risolvi?
No no... non lo so ancora, in realta', ma mi fido di te (prevedo cazziatone
:))... volevo dire: non capisco se il bug e' relativo all'autocomplete "di
per se'" oppure all'autocomplete insieme ad altre cose (nella fattispecie,
una richiesta httprequest sincrona in attesa di risposta).


 una richiesta httprequest sincrona in attesa di risposta).
Dovrebbe essere relativo alla gestione di alcuni eventi tastiera su elementi
input con autocomplete abilitato. Probabilmente hai un onkeypress/down/up su
quel campo.
-- 
~ "Viviamo dei vuoti lasciati da qualcun'altro."

 quel campo.
Infatti c'e'. Mi domando solo come mai il problema si verifica quando uso
richieste sincrone, mentre non appare quando uso richieste asincrone...


 richieste sincrone, mentre non appare quando uso richieste asincrone...
Il bug si verifica anche in assenza di XmlHttpRequest, se ti consola. Non
c'entra nulla. E' semplicemente il "come" si trova il browser in quel momento,
che lo fa scattare. Evidentemente le richieste in questione mettono la GUI
nello stato adatto a sollevare l'eccezione, ma quando mi ci sono imbattuto per
la prima volta non aveva nulla a che vedere con XHR.


 ha scritto:
[...]
Cerco di riassumere...
1) Riguardo a setTimeout/setInterval
Certo, ho intenzione di riscrivere la mia piccola chat senza operazioni
schedulate; il mio discorso su setTimeout/setInterval esulava, in effetti,
dal topic di questo thread: stavo cercando di capire "in generale" come
funzionano questi comandi e come risolvere il problema da te perfettamente
descritto e che ho sperimentato con un semplice script di prova. Riguardo a
quest'ultimo punto, vorrei si' arrivarci da solo... ma magari con un aiuto:
tu suggerisci di pianificare l'esecuzione di operazioni senza usare
setInterval oppure di usare setInterval ma apportando alcune correzioni per
risolvere il problema descritto? Poi: oltre al clearInterval, non c'e'
anche il clearTimeout per annullare l'esecuzione di una funzione
pianificata con setTimeout?
2) Riguardo alla chat
Mi dici che manca un pezzo di analisi... uhm... aiutami, se ti va, perche'
non capisco bene cosa manca (a parte il controllo degli errori, il login,
il logout).
3) Riguardo IRC
Ammetto le mie colpe... ma mi sento troppo vecchio e poco aperto verso il
prossimo, ora, per ovviare :)
Per il resto, mi e' tutto piuttosto chiaro.


 il logout).
Mi riferivo alla lettura dei messaggi. A meno che io non l'abbia persa nella
mia lettura fugace, nel tuo post riassuntivo non c'era.


 mia lettura fugace, nel tuo post riassuntivo non c'era.
In effetti era nascosta fra le righe... l'idea è quella di utilizzare un
solo oggetto http_req per qualunque operazione, sia essa di scrittura o di
lettura, con la differenza che solo per le operazioni di lettura vengono
inviati valori al server; la risposta del server conterrà, in ogni caso, i
nuovi messaggi da visualizzare nel client, nonché altre informazioni
(eventuali errori, utenti entrati/usciti etc.).
*Problema con setInterval*
Attraverso il comando setInterval, si pianifica l'operazione ripetuta di
una funzione, chiamiamola "func", a intervalli regolari di tempo (diciamo T
l'intervallo, e immaginiamolo pari a 1000). Se func, ad esempio, non fa
altro che scrivere nella pagina il tempo trascorso dall'ultima sua
esecuzione, l'output dovrebbe essere simile a:
0
1001
1003
1001
1002
1001
...
Possono, però, verificarsi dei casi in cui l'esecuzione di func è inibita
perché il motore javascript è "impegnato" nell'esecuzione di altri compiti;
in questo caso, l'output dell'esempio precedente potrebbe essere simile al
seguente:
0
1001
1002
11536
10
10
10
10
11
10
10
10
10
10
360
1002
Si nota, quindi, che una esecuzione di func avviene con notevole ritardo
(11000 invece di 1000); non appena si "libera" il motore javascript, le
successive esecuzioni di func si hanno, di fatto, una dopo l'altra,
praticamente senza intervallo, finché non si ripristina il funzionamento
normale.
Occorre trovare un metodo che consenta all'applicazione javascript di
riconoscere il verificarsi di una tale situazione e di impedire
l'esecuzione "a valanga" di func.
*Possibili soluzioni*
1. [your help needed here :-)]


 ha scritto:
[...]
Dopo un po', sono giunto a una nuova versione della mia cara chat...
Un solo oggetto xmlhttprequest; il logout viene effettuato utilizzando una
finta immagine. Tutto funziona... il problema dell'eccezione sollevata in
FireFox persiste, anche se capita mooooolto di rado e non crea problemi.
Credo che me lo terrň cosě com'č :-/
C'č anche una cosa che non so... nel momento in cui faccio una cosa del
tipo:
var i=new Image();
i.src="file.asp";
all'interno del gestore dell'evento onload, c'č il rischio che l'esecuzione
dello script "file.asp" non termini?


 dello script "file.asp" non termini?
Non capisco il senso della domanda...
-- 
- Se tu un Dio?
- N...no.
- E allora MUORI!
- Ray, se qualcuno ti chiede se sei un Dio, tu devi rispondere di sě!

 Non capisco il senso della domanda...
Mi spiego. Quando viene scatenato l'evento Unload, richiamo una funzione
"exit()" che deve richiedere il logout dalla chat; tale funzione in
sostanza fa questo:
var i=new Image();
i.src="chatlogout.asp";
dove "chatlogout.asp" è lo script che effettua il logout.
Essendo la funzione eseguita durante l'Unload della pagina, è possibile che
la nuova pagina venga caricata nel browser *prima* che chatlogout.asp abbia
terminato il suo compito. Mi chiedevo se questa eventualità comportasse
l'interruzione dell'esecuzione di chatlogout.asp... lo chiedo perché ho
dovuto inserire un ciclo di attesa nella funzione exit(): senza di esso il
logout *non viene* effettuato. Mi sono spiegato un po' meglio?


 logout *non viene* effettuato.
Strano. Come dissi all'inizio del thread, non ho mai fatto cose del genere. Ma
se il logout non viene effettuato significa semplicemente che la pagina non è
stata chiamata. Verifica che effettivamente venga richiamata.
-- 
- E.. lei è mestruata al momento?
- Ma scusi questo che c' entra??
- Si inchini alla scienza!

 Attento, che rischi il caching.
Sul resto, devo fare un po' di test... su questo, però, ti chiedo: intendi
che potrebbe non chiamare chatlogout.asp perché ha già l'"immagine" in
cache? Si può risolvere con un giochetto tipo
var d=new Date();
var i=new Image();
i.src="chatlogout.asp?dummy="+d.getTime();


 i.src="chatlogout.asp?dummy="+d.getTime();
Esatto pure questo.
-- 
- Egon, questo mi ricorda quando tentasti di trapanarti il cranio.
- Mi saebbe riuscito se non mi avessi fermato.

 Chiaramente, fallo solo se hai tempo da perdere :)
L'occhio ce l'ho buttato, ma c'è troppa roba per poter analizzare il tutto
velocemente. Dovrei perderci più tempo di quanto effettivamente possa fare;
anche perché adotti una logica diversa da quella che avrei adottato io
(timeout invece di interval, e la gestione della scrittura/lettura).
Le uniche cose che posso dirti sono:
a) Ho usato la chat un po', ma il problema con XmlHttpRequest non si è mai
verificato. Ergo, non sono riuscito a replicare l'errore, non so se accade in
condizioni particolari.
b) La chat non gestisce l'unicode: se utilizzo caratteri unicode per
registrare il mio nick, me lo "cambia" nelle corrispettive entities; mentre se
li uso per scrivere un messaggio mi appaiono dei punti interrogativi al loro
posto.
c) nella funzione stopCommunication, hai provato a invertire le istruzioni?
-- 
- Penso che sia meglio dividerci
- Buona idea
- SII, così possiamo fare più danno!!

 c) nella funzione stopCommunication, hai provato a invertire le istruzioni?
Ho fatto or ora questa prova, sembra non cambiare niente, il problema
persiste, sempre molto raro.


 della pagina avviene mentre una richiesta è in un determinato stato:
Beh, e non hai verificato in che stato fosse?
-- 
- Vuoi tu questo corpo?
- E' una domanda trabocchetto?

 Beh, e non hai verificato in che stato fosse?
Ho fatto un po' di debug. Si verifica un'eccezione, sempre (anche non
onunload), se si cerca di accedere alla proprietà status quando la
proprietà readyState ha valore 1. La cosa strana è che, quando si è nel
mezzo dell'evento unload, il test "if (oXmlHttp.readyState==4)" sembra
avere esito positivo, perché è solo nel ramo "then" (chiamiamolo così) che
vado poi ad accedere alla proprietà status...
Non ci sto capendo davvero niente.
Per dovere di cronaca, la funzione che gestisce il readyStateChange, col
debug, è questa:
this.showResults=function() {
// Gestisce i risultati della richiesta http
  var oXmlHttp=this.requestObject;
/* -------- DEBUG BEGIN */
  var debugReadyState="<li>readyState: x</li>";
  var debugStatus="<li>status: x</li>";
  var debugMessage="";
  var debugDiv=document.getElementById("debugid");
  try {
    debugReadyState="<li>readyState: "+oXmlHttp.readyState+"</li>";
  }
  catch(e) {
    debugMessage+="<li>ERROR readyState: "+e.message+"</li>";
  };
  try {
    debugStatus="<li>status: "+oXmlHttp.status+"</li>";
  }
  catch(e) {
    debugMessage+="<li>ERROR status: "+e.message+"</li>";
  };
  debugMessage+=debugReadyState+debugStatus;
  debugDiv.innerHTML+="<ul>"+debugMessage+"</ul>";
/* DEBUG END -------- */
  if (!this.communicationOn) return;
    if (oXmlHttp.readyState == 4) {
      if (oXmlHttp.status == 200) {
        var result=oXmlHttp.responseXML.documentElement;
        // usa il risultato...
      };
    };
};
Nella div di debug vengono visualizzate, per ogni richiesta xmlhttp
effettuata, le seguenti liste:
* ERROR status: Component returned failure code: 0x80040111
(NS_ERROR_NOT_AVAILABLE) [nsIXMLHttpRequest.status]
* readyState: 1
* status: x
* readyState: 2
* status: 200
* readyState: 3
* status: 200
* readyState: 4
* status: 200


 Non ci sto capendo davvero niente.
Purtroppo non posso analizzare il codice al posto tuo, ci metterei troppo
tempo per districarmi dalla logica applicativa. L'unica cosa che puoi fare è
tentare di replicare l'errore dell'onunload su una struttura più semplice.
(e se non accade, significa che è come hai strutturato la tua chat a generare
l'incongruenza).
Non mi hai poi detto se hai verificato che la richiesta dell'immagine parta (
mi riferisco al discorso dove mi dicevi di aver inserito un ciclo ).


 mi riferisco al discorso dove mi dicevi di aver inserito un ciclo ).
Non parte. Ho messo un alert all'inizio della funzione che effettua il
logout e in quel caso il logout viene effettuato correttamente. Non
capisco, davvero. Proverò a "ripulire" ancora la logica applicativa,
semplificherò... poi vediamo. Ti farò sapere :)


 logout e in quel caso il logout viene effettuato correttamente.
Ma anche no. Anzi, proprio no, era stato solo un caso, evidentemente.
Cosa strana: FireFox non fa il logout se premo sul pulsante "esci", mentre
Explorer non lo fa in caso di unload della pagina...


 Beh, ci devo provare... ma davvero non saprei come. Ci penserò...
Forza e coraggio. :)
-- 
- Ray è completamente partito Egon, di te che ne è restato?
- Mi dispiace Venkman,il terrore travalica la mia capacità di razionalizzare

 Explorer non lo fa in caso di unload della pagina...
Questa non l'ho ben capita, in verità. :) Ma facciamo che se ne riparla più
avanti quando avrai fatto un altro po' di test, altrimenti finisce che mi
confondo le idee e basta.
