L’evento di scaricamento può essere utilizzato per triggersre in modo affidabile una richiesta Ajax?

Ho bisogno di un metodo per monitorare le sessioni di modifica degli utenti, e una delle soluzioni che sto esaminando mi farà utilizzare un evento di unload per inviare una richiesta Ajax per informare il server della fine della sessione di modifica. (Vedi: Monitorare le sessioni utente per prevenire il conflitto di modifica )

La mia lettura (piuttosto limitata) sull’evento di unload indica che i codici allegati a questo gestore devono essere eseguiti rapidamente, e come tale viene in genere utilizzato per cancellare gli oggetti per evitare perdite di memoria.

La mia domanda è, può funzionare abbastanza in modo affidabile per questo scopo?

PS. So async: false opzione async: false .

Questo metodo è abbastanza affidabile, se il tuo server è abbastanza veloce da rispondere. Però qualcosa a cui prestare attenzione. Se chiudi il browser e invii la richiesta AJAX all’evento di scaricamento, è molto probabile che la risposta non venga ripristinata dal server in tempo prima che l’object della finestra venga distrutto. Quello che succede in questo caso (almeno con IE) è che orfana il tuo object di connessione e non lo chiude correttamente fino a quando non viene raggiunto il timeout della connessione. Se il tuo server non ha la connessione keep-alive triggersta, dopo aver chiuso 2 windows (lasciando aperta un’altra finestra), le connessioni aperte al server saranno esaurite (per IE6-7, per IE8 – 6 windows) e non sarai in grado di aprire il tuo sito web fino a quando non verrà raggiunto il timeout della connessione.

Mi sono imbattuto in una situazione del genere prima che stavo aprendo una finestra popup che stava inviando una richiesta AJAX allo scaricamento, era molto affidabile, ma era afflitta dall’emissione descritta sopra, e mi ci è voluto molto tempo per seguirla giù e capire cosa sta succedendo. Dopo ciò, ho fatto in modo che la finestra di apertura avesse lo stesso codice per chiamare il server, e su ogni scaricamento controllato per l’apertura e il codice lì eseguito se fosse presente.

Sembra che se chiudi l’ultima finestra del browser, IE distruggerà la connessione correttamente, ma se un’altra finestra è aperta, non lo farà.

PS E giusto per commentare la risposta sopra, AJAX non è veramente asincrono. Almeno l’implementazione di JS non lo è. Dopo aver inviato una richiesta, il codice JS sta ancora aspettando la risposta dal server. Non bloccherà l’esecuzione del codice, ma dal momento che il server potrebbe impiegare un po ‘di tempo per rispondere (o abbastanza a lungo per consentire a Windows di terminare l’object della finestra di IE), probabilmente si verificherà il problema descritto in precedenza.

Hai provato a usare

 var i = new Image(1,1); i.src='http://...' 

E solo restituendo qualche immagine vuota dal server. Penso che dovrebbe essere affidabile, lo script bloccherà. BTW: bello aggiungere timestamp per evitare il caching.

Abbiamo un caso in cui ne avevamo bisogno. È una pagina di report che ha bisogno di una memoria seria sul server, quindi volevamo liberarla immediatamente non appena uscivano dalla pagina. Abbiamo creato un set di frame e aggiunto l’handler di download lì. Il modo più affidabile era quello di impostare lo src di un’immagine sullo script di liberazione. Abbiamo effettivamente utilizzato sia lo scaricamento che onbeforeunload per la compatibilità tra browser. Non ha funzionato nei web kit nightly ma la gestione è stata OK con quello.

Tuttavia, quella non era la mia soluzione proposta. Userei un approccio heartbeat che richiede più lavoro ma è molto più robusto.

La tua pagina dovrebbe inviare periodiche richieste di battito cardiaco. Ogni richiesta imposta l’ultimo heartbeat da una pagina. È quindi necessario un thread che viene eseguito sul server e cancella la memoria se l’ultimo heartbeat era troppo tempo fa.

Questo non risolve il problema di lasciare la pagina in alto per molto tempo. Per questo è necessario un monitoraggio per l’attività dell’utente e lasciare la pagina dopo un periodo di inattività (assicurarsi di confermare con l’utente)

Dovrai fare i tuoi test sul fatto che il tuo particolare scenario funzioni o meno con il tempo che hai in unload , ma rendere la richiesta AJAX è piuttosto veloce, dal momento che AJAX è asincrono. Basta inviare la richiesta e il gioco è fatto! (Forse dovrai cancellare l’object richiesta che hai appena creato, però).

Se si desidera verificare che la richiesta AJAX sia stata eseguita, è necessario preoccuparsi di più / utilizzare l’opzione async:false (come indicato da questa discussione ). Ma, solo l’invio è un’operazione rapida “boom-and-hai-fatto”.

Avevo un caso in cui avevo solo bisogno di notificare al server lo scaricamento e non mi importava della risposta.

Se questo è il tuo caso puoi ignorare_user_abort e poi sai che succederà “in modo affidabile”