Impedisci qualsiasi forma di aggiornamento della pagina utilizzando jQuery / Javascript


92

Una volta che l'utente è sulla mia pagina, non voglio che aggiorni la pagina.

  1. In qualsiasi momento, l'utente F5preme o aggiorna il pulsante in alto. Dovrebbe ricevere un avviso che dice

    Non puoi aggiornare la pagina.

  2. Inoltre, se l'utente apre una nuova scheda e cerca di accedere allo stesso URL nella scheda precedente, dovrebbe ricevere un avviso

    Non è possibile aprire la stessa pagina in 2 schede

Comunque posso farlo usando JavaScript o jQuery? Il primo punto è davvero importante.


È possibile rilevare utilizzando l'API Broadcast Channel ( developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API ) e inviare messaggi per comunicare con le schede. COSÌ, utilizzando questo è possibile rilevare più schede con lo stesso URL e bloccare altre schede.
aXuser264

Risposte:


191

# 1 può essere implementato tramite window.onbeforeunload.

Per esempio:

<script type="text/javascript">
    window.onbeforeunload = function() {
        return "Dude, are you sure you want to leave? Think of the kittens!";
    }
</script>

All'utente verrà richiesto il messaggio e verrà data la possibilità di rimanere sulla pagina o continuare per la propria strada. Questo sta diventando sempre più comune. Stack Overflow fa questo se provi ad uscire da una pagina mentre stai scrivendo un post. Non puoi impedire completamente all'utente di ricaricare, ma puoi farlo sembrare davvero spaventoso se lo fa.

# 2 è più o meno impossibile. Anche se tenessi traccia delle sessioni e degli accessi degli utenti, non saresti comunque in grado di garantire di aver rilevato correttamente una seconda scheda. Ad esempio, forse ho una finestra aperta, quindi la chiudo. Adesso apro una nuova finestra. Probabilmente lo rileveresti come una seconda scheda, anche se ho già chiuso la prima. Ora il tuo utente non può accedere alla prima finestra perché l'ha chiusa e non può accedere alla seconda finestra perché lo stai negando.

In effetti, il sistema online della mia banca si sforza davvero di fare # 2 e la situazione sopra descritta si verifica continuamente. Di solito devo attendere la scadenza della sessione lato server prima di poter utilizzare nuovamente il sistema bancario.


1
Solo una nota che l'evento onbeforeunload non è disponibile nelle versioni del browser Opera.
WillyCornbread

1
C'è un modo per fare qualcosa se l'utente sceglie di rimanere sulla pagina.
riship89

5
Ha funzionato per me, anche se dovresti usare window.addEventListener (vedi developer.mozilla.org/en-US/docs/Web/Events/beforeunload ) invece, per la compatibilità cross-browser e per prevenire problemi con le librerie.
Julien Bérubé

So che questa domanda è vecchia ma, se volessero davvero impedire più sessioni, potrebbero usare WebSocket?
Meghan

1
@ Sean - Sì ... se davvero volessi impedire più sessioni. Un WebSocket può eseguire comunicazioni bidirezionali con stato. Il client (probabilmente) non diventerà improvvisamente qualcun altro mentre il WebSocket è connesso, quindi dovresti essere in grado di assegnare un token a quell'utente e cancellarlo una volta che il socket si chiude. Ma sta hackerando il comportamento previsto del programma utente, quindi probabilmente è una cattiva UX. Posso pensare a pochissimi casi in cui qualcosa del genere sarebbe appropriato (forse un gioco online - per impedire a qualcuno di accedere come due artigli della morte di livello 37 ...).
Seth

35

Non puoi impedire all'utente di aggiornare, né dovresti davvero provare. Dovresti tornare al motivo per cui hai bisogno di questa soluzione, qual è il problema alla radice qui ?. Inizia da lì e trova un modo diverso per risolvere il problema. Forse hai elaborato il motivo per cui pensi di aver bisogno di farlo, aiuterebbe a trovare una tale soluzione.

Rompere le funzionalità fondamentali del browser non è mai una buona idea, oltre il 99,999999999% di Internet funziona e si aggiorna con F5, questa è un'aspettativa dell'utente, che non dovresti infrangere.


Il problema è che la pagina è un'applicazione siebel. e quando un utente è in una sessione e preme Aggiorna, viene creata una nuova sessione e l'app si arresta in modo anomalo. quindi ho bisogno che l'utente non sia in grado di aggiornare.
pankaj

20
@pankaj: dovrebbe essere corretto sul sito dell'applicazione e cookie, ad esempio, in modo che l'utente condivida la sessione tra le schede.
Nick Craver

9
Non so da dove vieni qui. Innumerevoli siti su Internet impediscono l'aggiornamento del browser se il modulo è sporco, avvisandoti del fatto che potresti perdere le modifiche. Non sono sicuro del motivo per cui questo "rompa le funzionalità fondamentali del browser".
Siraris

1
@ Siraris: Esatto. Inoltre, sto creando un'applicazione privata che l'utente dovrebbe essere in grado di utilizzare anche quando non si trova nella sua rete privata. Quindi memorizzo tutto nella memoria del browser per l'utilizzo offline, ma se ricarica la pagina, l'intera applicazione è sparita. Potrebbe non essere molto "usuale", ma in questo moderno mondo IT lo diventerà sempre di più.
cslotty

16

Sebbene non sia una buona idea disabilitare il tasto F5, puoi farlo in JQuery come di seguito.

<script type="text/javascript">
function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };

$(document).ready(function(){
     $(document).on("keydown", disableF5);
});
</script>

Spero che questo ti aiuti!


27
Che dire di OSX, dove si trova CMD + R? O mobile dove c'è un pulsante da premere? Non la vedo come una soluzione
ItalyPaleAle

14

Ai vecchi tempi della CGI avevamo molte forme che avrebbero attivato varie azioni di backend. Come notifiche di testo a gruppi, lavori di stampa, raccolta di dati, ecc.

Se l'utente si trovava su una pagina che diceva "Attendi ... Esecuzione di un lavoro ENORME che potrebbe richiedere del tempo". Erano più propensi a premere REFRESH e questo sarebbe MALE!

PERCHÉ? Perché innescherebbe lavori più lenti e alla fine impantanerebbe l'intera faccenda.

La soluzione? Consenti loro di fare la loro forma. Quando inviano il modulo ... Inizia il tuo lavoro e poi indirizzali a un'altra pagina che dice loro di aspettare.

Dove la pagina al centro conteneva effettivamente i dati del modulo necessari per iniziare il lavoro. La pagina WAIT tuttavia contiene una distruzione della cronologia di javascript. Quindi possono RICARICARE quella pagina di attesa quanto vogliono e non attiverà mai l'avvio del lavoro originale in background poiché quella pagina WAIT contiene solo i dati del modulo necessari per WAIT stesso.

Spero che abbia un senso.

La funzione di distruzione della cronologia ha anche impedito loro di fare clic su INDIETRO e quindi di aggiornarsi.

È stato molto semplice e ha funzionato alla grande per MOLTI anni fino a quando il non profit è stato liquidato.

Esempio: MODULO DI ISCRIZIONE - Raccogli tutte le loro informazioni e quando inviate, questo attiva il tuo lavoro di backend.

RISPOSTA dalla voce del modulo - Restituisce HTML che esegue un reindirizzamento alla tua pagina di attesa statica e / o POST / GET a un altro modulo (la pagina WAIT).

PAGINA DI ATTESA - Contiene solo dati FORM relativi alla pagina di attesa e javascript per distruggere la cronologia più recente. Come (-1 OR -2) per distruggere solo le pagine più recenti, ma consente comunque loro di tornare alla loro pagina di immissione FORM originale.

Una volta che sono nella tua pagina WAIT, possono fare clic su REFRESH quanto vogliono e non genererà mai il lavoro FORM originale sul back-end. Invece, la tua pagina WAIT dovrebbe includere un aggiornamento temporizzato META stesso in modo che possa sempre controllare lo stato del loro lavoro. Quando il loro lavoro è completato, vengono reindirizzati dalla pagina di attesa dove desideri.

Se lo fanno manualmente AGGIORNAMENTO ... Stanno semplicemente aggiungendo un altro controllo del loro stato di lavoro lì.

Spero che aiuti. In bocca al lupo.


2
Non hai ricevuto abbastanza credito per questa risposta sorprendente e istruttiva. Grazie!!
ShiningLight


2

Il numero (2) è possibile utilizzando un'implementazione socket (come websocket, socket.io, ecc.) Con un heartbeat personalizzato per ogni sessione in cui è impegnato l'utente. Se un utente tenta di aprire un'altra finestra, devi controllare il gestore javascript con il server se va bene, quindi rispondi con un messaggio di errore.

Tuttavia, una soluzione migliore è sincronizzare le due sessioni, se possibile, come in Google Docs.


2

Il problema n. 2 ora può essere risolto utilizzando BroadcastAPI .

Al momento è disponibile solo in Chrome, Firefox e Opera.

var bc = new BroadcastChannel('test_channel');

bc.onmessage = function (ev) { 
    if(ev.data && ev.data.url===window.location.href){
       alert('You cannot open the same page in 2 tabs');
    }
}

bc.postMessage(window.location.href);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.