2009-12-17 18 views

risposta

29

Non è possibile. HTTP è un protocollo stateless, quindi non è possibile sapere quando un utente ha chiuso il browser o semplicemente sta seduto lì con una finestra aperta del browser senza fare nulla.

Ecco perché le sessioni hanno un timeout: è possibile provare a ridurre il timeout per chiudere più rapidamente le sessioni inattive, ma ciò potrebbe far sì che gli utenti legittimi abbiano il timeout della sessione in anticipo.

+14

facebook e gmail lo fanno ... qualcuno sa come ottengono questo? – NexusRex

+10

@NexusRex È possibile impostare un cookie di sessione che scade quando il browser viene chiuso. Ciò non fa scadere il lato server di sessione, ma il browser non avrà più il token. –

7

Come detto, il browser non consente al server di sapere quando si chiude.

Ancora, ci sono alcuni modi per ottenere vicino a questo comportamento. Puoi mettere un piccolo script AJAX sul posto che aggiorna regolarmente il server che il browser è aperto. Si dovrebbe accoppiare questo con qualcosa che si attiva sulle azioni fatte dall'utente, in modo da poter scadere una sessione inattiva e una che ha chiuso.

6

Come hai detto, la finestra di evento.onbeforeunload si attiva quando gli utenti fanno clic su un collegamento o aggiorna la pagina, quindi non sarebbe un buon risultato terminare una sessione.

http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx descrive tutte le situazioni in cui viene attivato window.onbeforeonload. (IE)

Tuttavia, è possibile posizionare una variabile globale JavaScript sulle proprie pagine per identificare le azioni che non devono attivare una disconnessione (utilizzando una chiamata AJAX da onbeforeonload, ad esempio).

Lo script di seguito si basa su JQuery

/* 
* autoLogoff.js 
* 
* Every valid navigation (form submit, click on links) should 
* set this variable to true. 
* 
* If it is left to false the page will try to invalidate the 
* session via an AJAX call 
*/ 
var validNavigation = false; 

/* 
* Invokes the servlet /endSession to invalidate the session. 
* No HTML output is returned 
*/ 
function endSession() { 
    $.get("<whatever url will end your session>"); 
} 

function wireUpEvents() { 

    /* 
    * For a list of events that triggers onbeforeunload on IE 
    * check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx 
    */ 
    window.onbeforeunload = function() { 
     if (!validNavigation) { 
     endSession(); 
     } 
    } 

    // Attach the event click for all links in the page 
    $("a").bind("click", function() { 
    validNavigation = true; 
    }); 

    // Attach the event submit for all forms in the page 
    $("form").bind("submit", function() { 
    validNavigation = true; 
    }); 

} 

// Wire up the events as soon as the DOM tree is ready 
$(document).ready(function() { 
    wireUpEvents(); 
}); 

Questo script può essere incluso in tutte le pagine

<script type="text/javascript" src="js/autoLogoff.js"></script> 

Andiamo attraverso questo codice:

var validNavigation = false; 

    window.onbeforeunload = function() { 
     if (!validNavigation) { 
     endSession(); 
     } 
    } 

    // Attach the event click for all links in the page 
    $("a").bind("click", function() { 
    validNavigation = true; 
    }); 

    // Attach the event submit for all forms in the page 
    $("form").bind("submit", function() { 
    validNavigation = true; 
    }); 

A globale la variabile è definita alla pagina livello. Se questa variabile non è impostata su true, l'evento windows.onbeforeonload terminerà la sessione.

Un gestore di eventi è collegato a ogni collegamento e modulo nella pagina per impostare questa variabile su true, impedendo così la chiusura della sessione se l'utente sta semplicemente inviando un modulo o facendo clic su un collegamento.

function endSession() { 
    $.get("<whatever url will end your session>"); 
} 

La sessione termina se l'utente chiude il browser/scheda o naviga. In questo caso la variabile globale non è stata impostata su true e lo script eseguirà una chiamata AJAX per qualsiasi URL desideri terminare la sessione

Questa soluzione è indipendente dalla tecnologia lato server. Non era exaustively testato, ma sembra funzionare bene nel mio test

+3

È importante notare che è necessario effettuare una richiesta Ajax * sincrona * o che è estremamente improbabile che venga espulso del tutto. E, naturalmente, le richieste Ajax sincrone sono brutte, collegano completamente l'interfaccia utente del browser. –

+0

@ T.J. Crowder: brutto è un eufemismo quando il tuo server ha problemi e un tempo di risposta tipico è più di 5 secondi :-) –

+1

commenti validi. Che ne dici di una chiamata AJAX di sincronizzazione con timeout molto piccolo ?. Si prega di considerare che la soluzione proposta non mira a risolvere tutti i problemi con le sessioni di orfani. Coprirebbe solo una percentuale (l'utente chiude attivamente il browser e l'URL di disconnessione risponde molto velocemente) –

4

lo faccio in questo modo:

$(window).bind('unload', function() { 
    if(event.clientY < 0) { 
     alert('Thank you for using this app.'); 
     endSession(); // here you can do what you want ... 
    } 
    }); 
window.onbeforeunload = function() { 
    $(window).unbind('unload'); 
    //If a string is returned, you automatically ask the 
    //user if he wants to logout or not... 
    //return ''; //'beforeunload event'; 
    if (event.clientY < 0) { 
     alert('Thank you for using this service.'); 
     endSession(); 
    } 
} 
+0

cosa succede se l'utente preme ALT + F4 ?? –

2

Non è possibile uccidere la variabile di sessione, quando la macchina unexpectly spegnimento per mancanza di corrente .È possibile solo quando l'utente è inattivo per un lungo periodo o è correttamente disconnesso.

+2

Lato server, non fa alcuna differenza se sei inattivo o se la tua macchina è spenta. lato client, non hai alcun controllo sulle variabili di sessione. – Alex

3

Si prega di fare riferimento alle fasi che seguono:

  1. creino anzitutto una pagina SessionClear.aspx e scrivere il codice per cancellare la sessione
  2. Quindi aggiungere seguente codice JavaScript nella tua pagina o pagina master:

    <script language="javascript" type="text/javascript"> 
        var isClose = false; 
    
        //this code will handle the F5 or Ctrl+F5 key 
        //need to handle more cases like ctrl+R whose codes are not listed here 
        document.onkeydown = checkKeycode 
        function checkKeycode(e) { 
        var keycode; 
        if (window.event) 
        keycode = window.event.keyCode; 
        else if (e) 
        keycode = e.which; 
        if(keycode == 116) 
        { 
        isClose = true; 
        } 
        } 
        function somefunction() 
        { 
        isClose = true; 
        } 
    
        //<![CDATA[ 
    
         function bodyUnload() { 
    
         if(!isClose) 
         { 
           var request = GetRequest(); 
           request.open("GET", "SessionClear.aspx", true); 
           request.send(); 
         } 
         } 
         function GetRequest() { 
          var request = null; 
          if (window.XMLHttpRequest) { 
           //incase of IE7,FF, Opera and Safari browser 
           request = new XMLHttpRequest(); 
          } 
          else { 
           //for old browser like IE 6.x and IE 5.x 
           request = new ActiveXObject('MSXML2.XMLHTTP.3.0'); 
          } 
          return request; 
         } 
        //]]> 
    </script> 
    
  3. Aggiungere il seguente codice nel tag body della pagina master.

    <body onbeforeunload="bodyUnload();" onmousedown="somefunction()"> 
    
1

Utilizzare questa:

window.onbeforeunload = function() { 
    if (!validNavigation) { 
     endSession(); 
    } 
} 

jsfiddle

Prevenire F5, formare presentare, ingresso clic e chiudere/terminare la sessione quando il browser o la scheda è chiuso, testato in IE8 + e browser moderni, divertiti!

+0

Si consideri che questa soluzione funziona solo nel caso in cui l'utente autorizzi l'esecuzione di JavaScript, quindi questo potrebbe essere un serio problema di sicurezza. – leiseliesel

+0

Per coloro che desiderano utilizzare questa soluzione a partire da oggi, questo codice non gestisce il pulsante di aggiornamento del browser premere, premere il pulsante indietro, premere il pulsante avanti e premere Invio nella barra dell'URL del browser. il logout viene attivato quando si verifica uno degli eventi menzionati e anche quando si chiude la scheda/browser – NAK

3

Non perfetto, ma la soluzione migliore per la società:

var spcKey = false; 
var hover = true; 
var contextMenu = false; 

function spc(e) { 
    return ((e.altKey || e.ctrlKey || e.keyCode == 91 || e.keyCode==87) && e.keyCode!=82 && e.keyCode!=116); 
} 

$(document).hover(function() { 
    hover = true; 
    contextMenu = false; 
    spcKey = false; 
}, function() { 
    hover = false; 
}).keydown(function (e) { 
    if (spc(e) == false) { 
     hover = true; 
     spcKey = false; 
    } 
    else { 
     spcKey = true; 
    } 
}).keyup(function (e) { 
    if (spc(e)) { 
     spcKey = false; 
    } 
}).contextmenu(function (e) { 
    contextMenu = true; 
}).click(function() { 
    hover = true; 
    contextMenu = false; 
}); 

window.addEventListener('focus', function() { 
    spcKey = false; 
}); 
window.addEventListener('blur', function() { 
    hover = false; 
}); 

window.onbeforeunload = function (e) { 
    if ((hover == false || spcKey == true) && contextMenu==false) { 
     window.setTimeout(goToLoginPage, 100); 
     $.ajax({ 
      url: "/Account/Logoff", 
      type: 'post', 
      data: $("#logoutForm").serialize(), 
     }); 
     return "Oturumunuz kapatıldı."; 
    } 
    return; 
}; 

function goToLoginPage() { 
    hover = true; 
    spcKey = false; 
    contextMenu = false; 
    location.href = "/Account/Login"; 
} 
5

Per il browser chiudere si può mettere sotto codice nel web.config:

<system.web> 
    <sessionState mode="InProc"></sessionState> 
</system.web> 

E distruggerà la sessione quando il browser viene chiuso, ma non funzionerà per la chiusura delle schede.

+0

Questo funziona? Si impara qualcosa di nuovo ogni giorno –

Problemi correlati