Registrazione dell'attività con l'API Web Beacon

Pubblicato: 2022-03-10
Riepilogo rapido ↬ L'API Beacon è un modo leggero ed efficiente per registrare le informazioni da una pagina Web a un server. Scopri come può essere utilizzato e cosa lo rende così diverso dalle tradizionali tecniche Ajax.

L'API Beacon è un'API Web basata su JavaScript per inviare piccole quantità di dati dal browser al server Web senza attendere una risposta. In questo articolo, esamineremo a cosa può essere utile, cosa lo rende diverso dalle tecniche familiari come XMLHTTPRequest ("Ajax") e come puoi iniziare a usarlo.

Se sai perché vuoi già utilizzare Beacon, sentiti libero di passare direttamente alla sezione Per iniziare.

A cosa serve l'API Beacon?

L'API Beacon viene utilizzata per inviare piccole quantità di dati a un server senza attendere una risposta . Quest'ultima parte è fondamentale ed è la chiave del perché Beacon è così utile: il nostro codice non riesce nemmeno a vedere una risposta, anche se il server ne invia una. I beacon sono specifici per inviare dati e poi dimenticarsene. Non ci aspettiamo una risposta e non otteniamo una risposta.

Pensala come una cartolina spedita a casa quando sei in vacanza. Ci metti una piccola quantità di dati (un po' di "Vorrei essere qui" e "Il tempo è stato bello"), li metti nella casella di posta e non ti aspetti una risposta. Nessuno invia una cartolina di ritorno dicendo "Sì, vorrei essere lì davvero, grazie mille!"

Per i siti Web e le applicazioni moderne, esistono numerosi casi d'uso che rientrano perfettamente in questo modello di invio e dimenticanza.

Altro dopo il salto! Continua a leggere sotto ↓

Statistiche di monitoraggio e dati analitici

Il primo caso d'uso che viene in mente alla maggior parte delle persone è l'analisi. Grandi soluzioni come Google Analytics potrebbero fornire una buona panoramica di cose come le visite alle pagine, ma cosa accadrebbe se volessimo qualcosa di più personalizzato? Potremmo scrivere del JavaScript per tenere traccia di ciò che sta accadendo in una pagina (forse come un utente interagisce con un componente, fino a che punto è passato o quali articoli sono stati visualizzati prima che seguano un CTA), ma poi dobbiamo inviare quei dati al server quando l'utente lascia la pagina. Beacon è perfetto per questo, poiché stiamo solo registrando i dati e non abbiamo bisogno di una risposta.

Non c'è motivo per cui non potremmo coprire anche il tipo di attività banali spesso gestite da Google Analytics, che riportano sull'utente stesso e sulle capacità del suo dispositivo e browser. Se l'utente ha una sessione di accesso, potresti persino ricollegare quelle statistiche a un individuo noto. Qualunque dato tu raccolga, puoi rispedirlo al server con Beacon.

Debug e registrazione

Un'altra applicazione utile per questo comportamento è la registrazione delle informazioni dal codice JavaScript. Immagina di avere un componente interattivo complesso sulla tua pagina che funziona perfettamente per tutti i tuoi test, ma che occasionalmente fallisce nella produzione. Sai che sta fallendo, ma non puoi vedere l'errore per iniziare il debug. Se riesci a rilevare un errore nel codice stesso, puoi quindi raccogliere la diagnostica e utilizzare Beacon per inviare tutto indietro per la registrazione.

In effetti, qualsiasi attività di registrazione può essere utilmente eseguita utilizzando Beacon, sia che si tratti di creare punti di salvataggio in un gioco, raccogliere informazioni sull'utilizzo delle funzionalità o registrare i risultati di un test multivariato. Se è qualcosa che accade nel browser di cui vuoi che il server venga a conoscenza, è probabile che Beacon sia un contendente.

Non possiamo già farlo?

So cosa stai pensando. Niente di tutto questo è nuovo, vero? Siamo in grado di comunicare dal browser al server utilizzando XMLHTTPRequest da oltre un decennio. Più recentemente abbiamo anche l'API Fetch che fa più o meno la stessa cosa con un'interfaccia più moderna basata su promesse. Detto questo, perché abbiamo bisogno dell'API Beacon?

La chiave qui è che, poiché non riceviamo una risposta, il browser può mettere in coda la richiesta e inviarla senza bloccare l'esecuzione di nessun altro codice. Per quanto riguarda il browser, non importa se il nostro codice è ancora in esecuzione o meno, o dove deve arrivare l'esecuzione dello script, poiché non c'è nulla da restituire può semplicemente inviare in background l'invio della richiesta HTTP finché non è conveniente invialo.

Ciò potrebbe significare attendere fino a quando il carico della CPU non è inferiore, o fino a quando la rete non è libera, o anche semplicemente inviarla immediatamente, se possibile. L'importante è che il browser metta in coda il beacon e restituisca immediatamente il controllo. Non tiene le cose mentre il beacon invia.

Per capire perché questo è un grosso problema, dobbiamo guardare come e quando questo tipo di richieste viene emesso dal nostro codice. Prendi il nostro esempio di uno script di registrazione di analisi. Il nostro codice potrebbe cronometrare quanto tempo gli utenti trascorrono su una pagina, quindi diventa fondamentale che i dati vengano rispediti al server all'ultimo momento possibile. Quando l'utente esce da una pagina, vogliamo interrompere i tempi e inviare i dati a casa.

In genere, utilizzeresti l'evento unload o beforeunload per eseguire la registrazione. Questi vengono attivati ​​quando l'utente fa qualcosa come seguire un collegamento sulla pagina per uscire. Il problema qui è che il codice in esecuzione su uno degli eventi di unload può bloccare l'esecuzione e ritardare lo scaricamento della pagina. Se lo scaricamento della pagina viene ritardato, anche il caricamento della pagina successiva viene ritardato e quindi l'esperienza sembra davvero lenta.

Tieni presente quanto possono essere lente le richieste HTTP. Se stai pensando alle prestazioni, in genere uno dei fattori principali che cerchi di ridurre sono le richieste HTTP aggiuntive perché andare in rete e ottenere una risposta può essere molto lento. L'ultima cosa che vuoi fare è mettere quella lentezza tra l'attivazione di un link e l'inizio della richiesta per la pagina successiva.

Beacon aggira questo problema mettendo in coda la richiesta senza bloccarla, restituendo immediatamente il controllo allo script. Il browser si occupa quindi di inviare quella richiesta in background senza bloccarla. Questo rende tutto molto più veloce, il che rende gli utenti più felici e ci consente di mantenere il nostro lavoro.

Iniziare

Quindi capiamo cos'è Beacon e perché potremmo usarlo, quindi iniziamo con un po' di codice. Le basi non potrebbero essere più semplici:

 let result = navigator.sendBeacon(url, data);

Il risultato è booleano, true se il browser ha accettato e messo in coda la richiesta e false se si è verificato un problema nel farlo.

Utilizzo navigator.sendBeacon()

navigator.sendBeacon accetta due parametri. Il primo è l'URL a cui effettuare la richiesta. La richiesta viene eseguita come HTTP POST, inviando tutti i dati forniti nel secondo parametro.

Il parametro data può essere in uno di diversi formati, tutti se presi direttamente dall'API Fetch. Questo può essere un Blob , un BufferSource , FormData o URLSearchParams , praticamente qualsiasi tipo di corpo utilizzato quando si effettua una richiesta con Fetch.

Mi piace usare FormData per i dati chiave-valore di base in quanto è semplice e facile da leggere.

 // URL to send the data to let url = '/api/my-endpoint'; // Create a new FormData and add a key/value pair let data = new FormData(); data.append('hello', 'world'); let result = navigator.sendBeacon(url, data); if (result) { console.log('Successfully queued!'); } else { console.log('Failure.'); }

Supporto del browser

Il supporto nei browser per Beacon è molto buono, con le uniche eccezioni degne di nota Internet Explorer (funziona in Edge) e Opera Mini. Per la maggior parte degli usi, dovrebbe andare bene, ma vale la pena testare il supporto prima di provare a usare navigator.sendBeacon .

È facile da fare:

 if (navigator.sendBeacon) { // Beacon code } else { // No Beacon. Maybe fall back to XHR? }

Se Beacon non è disponibile e la tua richiesta è importante, potresti ricorrere a un metodo di blocco come XHR. A seconda del tuo pubblico e scopo, potresti ugualmente scegliere di non preoccuparti.

Un esempio: registrazione del tempo su una pagina

Per vedere questo in pratica, creiamo un sistema di base per calcolare il tempo di permanenza di un utente su una pagina. Quando la pagina verrà caricata, prenderemo nota dell'ora e quando l'utente lascia la pagina invieremo l'ora di inizio e l'ora corrente al server.

Poiché ci preoccupiamo solo del tempo trascorso (non dell'ora effettiva della giornata), possiamo utilizzare performance.now() per ottenere un timestamp di base durante il caricamento della pagina:

 let startTime = performance.now();

Se concludiamo il nostro accesso in una funzione, possiamo chiamarla quando la pagina viene scaricata.

 let logVisit = function() { // Test that we have support if (!navigator.sendBeacon) return true; // URL to send the data to, eg let url = '/api/log-visit'; // Data to send let data = new FormData(); data.append('start', startTime); data.append('end', performance.now()); data.append('url', document.URL); // Let's go! navigator.sendBeacon(url, data); };

Infine, dobbiamo chiamare questa funzione quando l'utente lascia la pagina. Il mio primo istinto è stato quello di utilizzare l'evento di scaricamento, ma Safari su un Mac sembra bloccare la richiesta con un avviso di sicurezza, quindi beforeunload unload bene per noi qui.

 window.addEventListener('beforeunload', logVisit);

Quando la pagina viene scaricata (o, appena prima che lo faccia) verrà chiamata la nostra funzione logVisit() e a condizione che il browser supporti l'API Beacon, il nostro beacon verrà inviato.

(Nota che se non c'è il supporto Beacon, restituiamo true e facciamo finta che tutto abbia funzionato alla grande. La restituzione di false annullerebbe l'evento e interromperebbe lo scaricamento della pagina. Sarebbe un peccato.)

Considerazioni durante il monitoraggio

Poiché molti dei potenziali usi di Beacon ruotano attorno al monitoraggio delle attività, penso che sarebbe negligente non menzionare le responsabilità sociali e legali che abbiamo come sviluppatori quando registriamo e monitoriamo attività che potrebbero essere legate agli utenti.

GDPR

Potremmo pensare alle recenti leggi europee GDPR come relative all'e-mail, ma ovviamente la legislazione riguarda la conservazione di qualsiasi tipo di dato personale. Se sai chi sono i tuoi utenti e puoi identificare le loro sessioni, dovresti controllare quale attività stai registrando e come si collega alle tue politiche dichiarate.

Spesso non abbiamo bisogno di tracciare tanti dati quanto il nostro istinto ci dice che dovremmo. Può essere meglio non memorizzare deliberatamente informazioni che identificherebbero un utente e quindi ridurre la probabilità di sbagliare.

DNT: non tenere traccia

Oltre ai requisiti legali, la maggior parte dei browser dispone di un'impostazione per consentire all'utente di esprimere il desiderio di non essere tracciato. Do Not Track invia un'intestazione HTTP con la richiesta simile a questa:

 DNT: 1

Se stai registrando dati che possono tracciare un utente specifico e l'utente invia un'intestazione DNT positiva, sarebbe meglio seguire i desideri dell'utente e rendere anonimi quei dati o non seguirli affatto.

In PHP, ad esempio, puoi testare molto facilmente questa intestazione in questo modo:

 if (!empty($_SERVER['HTTP_DNT'])) { // User does not wish to be tracked ... }

In conclusione

L'API Beacon è un modo davvero utile per inviare i dati da una pagina al server, in particolare in un contesto di registrazione. Il supporto del browser è molto ampio e ti consente di registrare i dati senza interruzioni senza influire negativamente sull'esperienza di navigazione dell'utente e sulle prestazioni del tuo sito. La natura non bloccante delle richieste significa che le prestazioni sono molto più veloci rispetto ad alternative come XHR e Fetch.

Se desideri saperne di più sull'API Beacon, vale la pena dare un'occhiata ai seguenti siti.

  • "Specifica W3C Beacon", Raccomandazione del candidato W3C
  • "Documentazione MDN Beacon", documenti Web MDN, Mozilla
  • "Informazioni di supporto del browser", caniuse.com