2015-12-07 13 views
20

Il mio obiettivo è rimuovere i cookie utente quando la scheda del browser è chiusa.Come posso gestire l'evento di chiusura della scheda del browser in Angolare? Solo chiudere, non aggiornare

È possibile? Posso gestire l'evento di chiusura della scheda del browser senza refresh case?

Se utilizzo gli eventi beforeunload o unload, la funzione viene attivata quando si aggiorna la pagina utente, non voglio ciò, voglio solo eseguire la scheda chiusa.

Come posso fare questo in Angolare?

+0

Provare questa volta: angular.element ($ window) .bind ("beforeunload", methodToCall) – Ved

+0

L'ho provato in .run() ma non sembra funzionare. –

+0

qual è il problema che hai dovuto affrontare con questo codice? – Ved

risposta

6

Questo è, tragicamente, non è un problema semplice da risolvere. Ma può essere fatto. La risposta sotto è amalgamata da molte diverse risposte SO.

Parte semplice: Conosciuto che la finestra viene distrutta. È possibile utilizzare l'handle di evento onunload per rilevare questo.

Tricky Parte:

Rilevare se si tratta di un aggiornamento, seguono collegamento o la finestra desiderata evento close. Rimozione di collegamento segue e l'invio di moduli è abbastanza facile:

var inFormOrLink; 
$('a').live('click', function() { inFormOrLink = true; }); 
$('form').bind('submit', function() { inFormOrLink = true; }); 

$(window).bind('beforeunload', function(eventObject) { 
    var returnValue = undefined; 
    if (! inFormOrLink) { 
     returnValue = "Do you really want to close?"; 
    } 
    eventObject.returnValue = returnValue; 
    return returnValue; 
}); 

di soluzione

Controllo event.clientY o event.clientX per determinare ciò che è stato cliccato per generare l'evento Povero-man.

function doUnload(){ 
if (window.event.clientX < 0 && window.event.clientY < 0){ 
    alert("Window closed"); 
} 
else{ 
    alert("Window refreshed"); 
} 
} 

asse Y non funziona causa è negativo per i clic sulla finestra vicino pulsanti ricarica o scheda/e positivo quando tasti indicati sono utilizzati per ricaricare (es F5, Ctrl-R, ...) e chiusura della finestra (ad es. Alt-F4). X-Axis non è utile poiché diversi browser hanno posizionamenti di pulsanti diversi. Tuttavia, se sei limitato, eseguire le coordinate dell'evento attraverso una serie di if-els potrebbe essere la soluzione migliore. Attenzione che questo non è certamente affidabile.

Coinvolto Soluzione

(Tratto da Julien Kronegg) Utilizzo di memoria locale di HTML5 e comunicazione AJAX client/server. Avvertenza: questo approccio è limitato ai browser che supportano l'archiviazione locale HTML5.

Sulla tua pagina, aggiungere un onunload alla finestra per il seguente gestore

function myUnload(event) { 
    if (window.localStorage) { 
     // flag the page as being unloading 
     window.localStorage['myUnloadEventFlag']=new Date().getTime(); 
    } 

    // notify the server that we want to disconnect the user in a few seconds (I used 5 seconds) 
    askServerToDisconnectUserInAFewSeconds(); // synchronous AJAX call 
} 

quindi aggiungere un onloadon il corpo per il seguente gestore

function myLoad(event) { 
    if (window.localStorage) { 
     var t0 = Number(window.localStorage['myUnloadEventFlag']); 
     if (isNaN(t0)) t0=0; 
     var t1=new Date().getTime(); 
     var duration=t1-t0; 
     if (duration<10*1000) { 
      // less than 10 seconds since the previous Unload event => it's a browser reload (so cancel the disconnection request) 
      askServerToCancelDisconnectionRequest(); // asynchronous AJAX call 
     } else { 
      // last unload event was for a tab/window close => do whatever 
     } 
    } 
} 

Sul server, raccogliere le richieste di disconnessione in un elenco e impostare un thread del timer che ispeziona l'elenco a intervalli regolari (ho utilizzato ogni 20 secondi). Una volta scaduto il timeout della richiesta di disconnessione (ovvero i 5 secondi mancanti), disconnettere l'utente dal server. Se nel frattempo viene ricevuta una cancellazione della richiesta di disconnessione , la richiesta di disconnessione corrispondente di viene rimossa dall'elenco, in modo che l'utente non venga disconnesso.

Questo approccio è applicabile anche se si desidera distinguere tra l'evento di chiusura della scheda/finestra seguito da collegamenti o modulo inviato. Devi solo aggiungere e moduli e in ogni pagina di destinazione link/modulo.

Commenti di chiusura (gioco di parole):

Dal momento che si desidera rimuovere i cookie quando la finestra è chiusa, sto supponendo che sia per impedire loro di essere utilizzati in una sessione futura. Se questo è un presupposto corretto, l'approccio sopra descritto funzionerà bene. Si mantiene il cookie invalido sul server (una volta disconnesso il client), quando il client crea una nuova sessione, il JS invierà il cookie per impostazione predefinita, a quel punto si sa che proviene da una sessione precedente, eliminarlo e facoltativamente fornire un nuovo da impostare sul client.

+1

Grazie per il tuo impegno amico mio. Questa risposta è stata di grande aiuto. –

+0

@ FurkanBaşaran Siete i benvenuti :) –

+0

avete avuto qualche idea per farlo in angular2. – CTN

6
$window.addEventListener("beforeunload", function (e) { 
    var confirmationMessage = "\o/"; 
    console.log("closing the tab so do your small interval actions here like cookie removal etc but you cannot stop customer from closing"); 
    (e || window.event).returnValue = confirmationMessage; //Gecko + IE 
    return confirmationMessage;       //Webkit, Safari, Chrome 
}); 

Questo è abbastanza discusso sul fatto che possiamo farlo o no in modo infallibile. Ma tecnicamente non molte cose possono essere fatte qui poiché il tempo che hai è piuttosto basso e se il cliente lo chiude prima che le tue azioni siano complete, sei nei guai e sei completamente alla mercé del cliente. Non dimenticare di inserire una finestra $. Consiglio di non dipendere da ciò.

javascript detect browser close tab/close browser

Aggiornamento: ero alla ricerca di questo problema insieme ad alcune raccomandazioni. E oltre a questa opzione sopra, il modo migliore per gestire questi casi è creare sessioni senza timeout di attività di 25-30 minuti. Converti tutti i cookie che devono essere distrutti in sessioni con timeout. In alternativa, è possibile impostare la scadenza del cookie, ma il cookie rimane nel browser fino al successivo accesso. Meno di 25-30 minuti di inattività della sessione non è completamente affidabile poiché è possibile disconnettersi se il client non utilizza il browser per 10-15 minuti. Ho anche provato gli eventi di cattura da link (a>) o (< submit>) o (keypress) eventi basati. Il problema è che gestisce bene l'aggiornamento della pagina. Ma non rimuove il problema del client di chiudere il browser o la scheda del browser prima che i cookie vengano cancellati. È qualcosa che devi considerare nel tuo caso d'uso e scambiare con forza a causa di nessun controllo su di esso. Meglio cambiare il design sulla sua dipendenza con un'architettura migliore che affrontare problemi menzionati in seguito.

+0

Grazie, Gary, ho appena visto l'aggiornamento della tua risposta. –

0

Se il tuo obiettivo è rimuovere i cookie quando il browser è chiuso, non impostare la scadenza. I cookie senza scadenza vengono rimossi alla chiusura del browser.

In realtà non dovrebbe mai essere necessario sapere se un utente chiude il browser o meno. Sono fiducioso che ci sono modi alternativi per realizzare qualunque cosa tu voglia fare.

La linea di fondo:

Se un visitatore non è sulla tua pagina più, è davvero non sono affari tuoi ciò che l'utente sta facendo con il proprio browser o il loro computer. Quindi la rilevazione della chiusura del browser probabilmente non verrà mai implementata senza una sorta di scelta dell'utente finale, ad esempio estensioni/plug-in del browser.

1

So che è passato un po 'di tempo da quando è stata posta questa domanda, ma ho pensato di dare anche la mia risposta. Il modo migliore in cui ho trovato di ricaricare la pagina senza perdere i cookie e rimuovere i cookie nella finestra o nella chiusura delle schede era usare ng-keydown per guardare F5 Keypress (KeyCode 116).

HTML

<body ng-controller="exitController" ng-keydown="isRefresh($event)"> 

CONTROLLER

yourApp.controller('exitController', ['$rootScope', '$scope', '$window', '$cookies', function($rootScope, $scope, $window, $cookies) { 
//set refresh to false to start out, it will become true only when we hit the refresh page 
$scope.refresh = false; 

//This is where we'll actually clear our cookies in the event of a window close 
$scope.clearCookies = function() { 
    $cookies.remove('sessionData'); 
    $cookies.remove('ss-id'); 
    $cookies.remove('ss-pid'); 
}; 

//When the user types any key, it will be assessed. 
$scope.isRefresh = function(e) { 
    var keyCode = e.keyCode; //find the key that was just pressed 
    if(keyCode === 116) { //if the key that was pressed is F5, then we know it was a refresh 
     $scope.refresh = true; 
    } 
} 

//event that handles all refresh requests 
window.onbeforeunload = function (e) { 
    if (!$scope.refresh) { //as long as the trigger for the refresh wasnt initiated by F5, we remove the cookies 
     $scope.clearCookies(); 
    } 
}; 

}]);

Problemi correlati