2009-06-17 9 views
28

Devo rilevare quando un utente non è attivo (non fa clic o non scrive) nella pagina corrente per più di 30 minuti.Come posso rilevare con JavaScript/jQuery se l'utente è attualmente attivo sulla pagina?

Penso che potrebbe essere meglio utilizzare un evento blolling collegato al tag body e quindi continuare a reimpostare un timer per 30 minuti, ma non sono esattamente sicuro di come creare questo.

Ho jQuery disponibile, anche se non sono sicuro di quanto effettivamente utilizzerò jQuery.

Edit: Sono più bisogno di sapere se stanno attivamente utilizzando il sito, quindi fare clic (cambiando campi o posizione all'interno di un campo o selezionando le caselle di controllo/radio) o di battitura (in un ingresso, textarea, ecc) . Se sono in un'altra scheda o utilizzano un altro programma, suppongo che non stiano utilizzando il sito e che pertanto debbano essere disconnessi (per motivi di sicurezza).

Modifica # 2: Quindi tutti sono chiari, questo non è affatto per determinare se l'utente è loggato, autenticato o altro. In questo momento il server effettuerà il login dell'utente se non effettua una richiesta di pagina entro 30 minuti. Questa funzionalità impedisce i tempi in cui qualcuno spende più di 30 minuti per compilare un modulo e quindi invia il modulo solo per scoprire che non sono stati disconnessi. Pertanto, questo verrà utilizzato in combinazione con il sito del server per determinare se l'utente è inattivo (non facendo clic o digitando). Fondamentalmente, l'accordo è che dopo 25 minuti di inattività, verrà presentata una finestra di dialogo per inserire la password. Se non lo fanno entro 5 minuti, il sistema li registra automaticamente e la sessione del server viene disconnessa (la prossima volta che si accede a una pagina, come nella maggior parte dei siti).

Javascript è utilizzato solo come avvertimento per l'utente. Se JavaScript è disabilitato, non riceveranno l'avviso e (insieme alla maggior parte del sito non funzionante) verranno disconnessi la prossima volta che richiederanno una nuova pagina.

+0

Registrazione persone fuori solo per cambiare le schede è probabilmente una cattiva idea - che cosa se avevano bisogno di andare in un'altra scheda o un programma per ottenere informazioni per accedere al tuo modulo, e tornare a scoprire che hai stato disconnesso? Prima di procedere, è necessario considerare prima se è necessario. –

+1

È completamente necessario. Sì, è fastidioso, ma necessario perché abbiamo a che fare con i dati di risposta alle emergenze (ad esempio, gasdotti esplodono) e abbiamo bisogno di mantenere i dati al sicuro e purtroppo gli utenti non sono sempre su macchine sicure (posizione). Non possiamo avere persone sedute e usare l'account di qualcun altro. –

+2

Ok, ma non dimenticare che JS non è affidabile per la maggior parte delle attività sicure, poiché quasi tutti i browser hanno un meccanismo per disattivarlo. Avrai davvero voglia di calcolare il tempo massimo per sederti su una pagina, quindi ogni volta che una pagina viene caricata, memorizzare il timestamp da qualche parte, quindi ogni lato del server d'azione dovrebbe essere controllato contro questo prima di fare qualsiasi cosa. –

risposta

13

È possibile guardare mouse movement, ma questo è il meglio che si ottiene per l'indicazione di un utente ancora presente senza ascoltare l'evento click. Ma non c'è modo per javascript per dire se è la scheda attiva o se il browser è addirittura aperto. (beh, potresti ottenere la larghezza e l'altezza del browser e questo ti direbbe se è stato minimizzato)

+0

anche tu puoi guardare l'evento keyup – TStamper

+0

L'OP ha detto di non cliccare e non digitare, quindi ci sarebbe nessun evento di keyup. – Malfist

+2

cosa vuoi dire non ci sarebbe nessun evento keyup? Quando l'utente interrompe la digitazione, questo è l'ultimo evento di keyup e avendo un evento della funzione keyup non è sufficiente controllare per vedere quanto tempo fa si è verificato l'evento keyup – TStamper

3

Utilizzando jQuery, puoi facilmente controllare il movimento del mouse e usarlo per impostare una variabile che indica l'attività su true, quindi usando vanilla javascript, puoi controllare questa variabile ogni 30 minuti (o qualsiasi altro intervallo) per vedere se è vera. Se è falso, esegui la tua funzione o altro. Cercare setTimeout e setInterval per eseguire i tempi. Probabilmente dovrai anche eseguire una funzione ogni minuto per reimpostare la variabile su false.

2

Qui il mio colpo:

var lastActivityDateTime = null; 

function checkActivity() 
{ 
    var currentTime = new Date(); 
    var diff = (lastActivityDateTime.getTime() - currentTime.getTime()); 
    if (diff >= 30*60*1000) 
    { 
     //user wasn't active; 
     ... 
    } 
    setTimeout(30*60*1000-diff, checkActivity); 
} 

setTimeout(30*60*1000, checkActivity); // for first time we setup for 30 min. 


// for each event define handler and inside update global timer 
$("body").live("event_you_want_to_track", handler); 

function handler() 
{ 
    lastActivityDateTime = new Date(); 
    // rest of your code if needed. 
} 
+0

2 domande: (1) c'è un motivo per cui non si limiterebbe a mantenere il timer e (2) perché utilizzare live? Il tag del corpo non viene mai rimosso o aggiunto, o mi manca qualcosa? –

+0

1. Sto reimpostando il timer o non ho capito la tua domanda. 2. Usato dal vivo, solo perché 5 sec. prima usato nel mio codice. –

+0

@ Artem- live() è per cercare nuovi elementi creati dinamicamente – TStamper

14

Sono recentemente ha fatto qualcosa di simile, anche se con Prototype invece di JQuery, ma immagino l'attuazione sarebbe più o meno lo stesso a patto che JQuery supporta gli eventi personalizzati.

In breve, IdleMonitor è una classe che osserva eventi di mouse e tastiera (regolare di conseguenza in base alle proprie esigenze). Ogni 30 secondi reimposta il timer e trasmette uno stato: evento inattivo, a meno che non riceva un evento mouse/chiave, nel qual caso trasmette uno stato: evento attivo.

var IdleMonitor = Class.create({ 

    debug: false, 
    idleInterval: 30000, // idle interval, in milliseconds 
    active: null, 
    initialize: function() { 
     document.observe("mousemove", this.sendActiveSignal.bind(this)); 
     document.observe("keypress", this.sendActiveSignal.bind(this)); 
     this.timer = setTimeout(this.sendIdleSignal.bind(this), this.idleInterval); 
    }, 

    // use this to override the default idleInterval 
    useInterval: function(ii) { 
     this.idleInterval = ii; 
     clearTimeout(this.timer); 
     this.timer = setTimeout(this.sendIdleSignal.bind(this), ii); 
    }, 

    sendIdleSignal: function(args) { 
     // console.log("state:idle"); 
     document.fire('state:idle'); 
     this.active = false; 
     clearTimeout(this.timer); 
    }, 

    sendActiveSignal: function() { 
     if(!this.active){ 
      // console.log("state:active"); 
      document.fire('state:active'); 
      this.active = true; 
      this.timer = setTimeout(this.sendIdleSignal.bind(this), this.idleInterval); 
     } 
    } 
}); 

Poi ho creato un'altra classe che ha il seguente da qualche parte in esso:

Event.observe(document, 'state:idle', your-on-idle-functionality); 
Event.observe(document, 'state:active', your-on-active-functionality) 
20

questo è quello che è venuta in mente. Sembra funzionare nella maggior parte dei browser, ma voglio essere sicuro che funzionerà ovunque, per tutto il tempo:

var timeoutTime = 1800000; 
var timeoutTimer = setTimeout(ShowTimeOutWarning, timeoutTime); 
$(document).ready(function() { 
    $('body').bind('mousedown keydown', function(event) { 
     clearTimeout(timeoutTimer); 
     timeoutTimer = setTimeout(ShowTimeOutWarning, timeoutTime); 
    }); 
}); 

Chiunque veda problemi?

+2

Un piccolo problema: ti consigliamo di cancellare il timer esistente prima di avviarne un altro! Ho modificato questo cambiamento in ... – Shog9

+0

Thxs Shog9, mi sono sempre chiesto questo. Ma, non cancellerebbe il timer esistente sovrascrivendo la variabile con un nuovo timer? –

+2

No, la variabile è solo un ID timer, il timer stesso è una struttura interna del browser. Memorizzare l'ID in una variabile è solo un modo semplice per identificare la struttura interna del browser per la funzione clearTimeout. – Breton

2

Se si tratta di un problema di sicurezza, fare questo clientide con javascript è assolutamente l'estremità sbagliata della pipe per eseguire questo controllo. L'utente potrebbe facilmente avere javascript disabilitato: cosa fa la tua applicazione allora? Cosa succede se l'utente chiude il proprio browser prima del timeout. si disconnettono mai?

La maggior parte dei framework server ha un tipo di impostazione di timeout della sessione per gli accessi. Usalo e risparmia il lavoro di ingegneria.

Non si può fare affidamento sul presupposto che le persone non possono accedere senza javascript, quindi l'utente ha javascript. Tale assunto non è un deterrente per qualsiasi aggressore determinato, o anche educato modestamente.

L'uso di javascript è come una guardia di sicurezza che consegna ai clienti la chiave del caveau di una banca. L'unico modo in cui funziona è sulla fede.

Per favore, credetemi quando dico che l'uso di javascript in questo modo (e che richiede javascript per gli accessi !!) è un modo incredibilmente potente per progettare qualsiasi tipo di app web.

+0

Un commento però. Se l'applicazione utilizza una sorta di richieste ajax temporizzate per mantenere aggiornate le informazioni, questo potrebbe aggiornare il timeout della sessione sul server, quindi tenere traccia degli eventi di clic e inviare queste informazioni con i parametri di richiesta ajax renderebbe più semplice il "rilevamento" di uno stato di inattività – gnarf

+1

Sì, questo è un commento corretto. gatekeeper dovrebbe trovarsi sul server, non sul client.Le informazioni complementari dal client potrebbero essere utili, ma è importante pianificare l'errore e non venire a dipendere dal codice lato client per motivi di sicurezza – Breton

1

Senza usare JS, un modo più semplice (e più sicuro) sarebbe semplicemente avere un timestamp lastActivity memorizzato con la sessione dell'utente e controllarlo al caricamento della pagina. Supponendo che si sta utilizzando PHP (si può facilmente ripetere questo codice per un'altra piattaforma):

if(($_SESSION['lastAct'] + 1800) < time()) { 
    unset($_SESSION); 
    session_destroy(); 
    header('Location: session_timeout_message.php'); 
    exit; 
} 

$_SESSION['lastAct'] = time(); 

e aggiungere questo nella tua pagina (opzionale, l'utente verrà disconnesso a prescindere se la pagina viene aggiornata o meno (come si disconnette nel registro della pagina successiva)).

<meta http-equiv="refresh" content="1801;" /> 
+0

Sì, ho già questo. solo un avvertimento per aiutare l'utente in modo che non perda le informazioni.Questa non è la procedura di autenticazione per il sito !! –

+0

In caso di bisogno basta calcolare il tempo dall'ultima richiesta (se sei non usando Ajax, questo è semplice. In caso contrario, sarà necessario aggiornare una variabile ogni volta che viene effettuata una richiesta Ajax). Se non è stata effettuata alcuna richiesta nell'ultimo, diciamo 20 minuti, viene visualizzato un avviso che indica che la sessione scade tra 10 minuti. –

0

Se la preoccupazione è la perdita di informazioni per l'utente dopo un timeout di accesso; un'altra opzione sarebbe quella di archiviare semplicemente tutte le informazioni registrate all'apertura di una nuova sessione (una nuova sessione verrà sempre avviata quando la sessione precedente è stata chiusa/scartata dal server) quando la richiesta a una pagina viene effettuata prima di instradamento alla pagina di registrazione. Se l'utente accede correttamente, è possibile utilizzare queste informazioni salvate per riportare l'utente a dove si trovava. In questo modo, anche se l'utente si allontana per alcune ore, può sempre tornare dove si trovava dopo un login riuscito; senza perdere alcuna informazione.

Questo richiede più lavoro da parte del programmatore, ma è una grande funzionalità totalmente apprezzata dagli utenti. Apprezzano in particolare il fatto che possono concentrarsi completamente su ciò che devono fare senza sottolineare la possibilità di perdere le loro informazioni ogni 30 minuti circa.

13

Ifvisible.js è una soluzione leggera crossbrowser che fa proprio questo. Può rilevare quando l'utente passa a un'altra scheda e torna alla scheda corrente. Può anche rilevare quando l'utente diventa inattivo e diventa di nuovo attivo. È piuttosto flessibile

+0

si prega di fornire più informazioni di un semplice collegamento – slfan

+1

migliore risposta per me (: – Flezcano

+0

migliore soluzione per me. – Macumbaomuerte

2

Ifvisible è una buona libreria JS per verificare l'inattività dell'utente.

ifvisible.setIdleDuration(120); // Page will become idle after 120 seconds 

ifvisible.on("idle", function(){ 
    // do something 
}); 
Problemi correlati