Faire un appel Ajax sur un "unload"
Parfois, vous allez avoir le besoin suivant: envoyer une requête au serveur au moment du déchargement de la page (que ce soit sur un simple "refresh" ou lors d'un changement dans la navigation utilisateur).
Nous allons tout naturellement écouter l'événement JavaScript "unload" et faire notre appel Ajax ou Fetch.
Le hic est que:
- Soit l'appel n'aura pas le temps de partir
- Soit l'appel sera annulé (le navigateur aura commencé à l'initialiser, peut-être même commencer à le soumettre, mais va tout arrêté).
Bref, il y a à peu prêt 95% de chances que la requête n'atteigne jamais le serveur.
Une solution basique est de faire un appel Ajax synchrone. Mais cela est fortement déconseillé car cela frisse l'IHM.
Une nouvelle solution est d'utiliser le "Beacon".
Ce dernier a pour objectif de soumettre une requête Ajax, et quelle soit émise dans tous les cas. Cela veut dire que même si l'utilisateur ferme le navigateur, un process sera lancé en arrière-plan afin de s'assurer que la requête est complêtement exécuté.
Voici un exemple tout bête d'utilisation (issue de ce lien):
window.addEventListener('unload', logData, false); function logData() { navigator.sendBeacon("/log", analyticsData); }
En fait, si nous devions faire un "équivalent" sans l'api Beacon, ce serait:
window.addEventListener('unload', logData, false); function logData() { var client = new XMLHttpRequest(); client.open("POST", "/log", false); // third parameter indicates sync xhr. :( client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); client.send(analyticsData); }
Autrement dit, pour pouvoir utiliser l'api Beacon, il faut taper sur un endpoint avec la méthode HTTP POST (ce qui en fonction de votre besoin, peut ne pas être très REST).
A l'heure actuel, le Beacon est plutôt bien répandu (au pire des cas, nous pouvons faire un fallback sur l'équivalent en mode Ajax synchrone):
Dans un futur plutôt proche, l'api Fetch aura l'option "keepalive" qui permettra d'autoriser la requête d'être exécuté quoi qu'il advienne, sans avoir à utiliser l'api Beacon et sans forcément être en méthode POST.
Ceci est toujours en cours de réflexion et d'implémentation: https://www.chromestatus.com/feature/5760375567941632
Mais tout cela nous permet de faire enfin des traitement asynchrones sur des événements qui ne l'autorisent pas de base.
Enjoy!
Commentaires
Enregistrer un commentaire