J'essaie de créer une fonctionnalité de session de relecture utilisateur pour un site Web et j'utilise la bibliothèque rrweb pour ce faire.
Ce que fait cette bibliothèque, c'est lors de l'enregistrement : elle capture tous les événements de la page Web et je peux les transmettre à la fonction de relecture, qui gère la relecture de session, en les stockant dans array
中来保存这些事件,当我想重播会话时,我只需将 array
.
Actuellement, à des fins de test, j'enregistre ce tableau dans mon sessionStorage
中,每次发出新事件时,我都会获取 array
然后将该新事件推送到其中,然后再次将 sessionStorage
保存在我的 sessionStorage
comme ceci : < /p>
rrweb.record({ emit(event) { const sessions = JSON.parse(sessionStorage.getItem('sessions')) || []; sessions.push(event); sessionStorage.setItem('sessions', JSON.stringify(sessions)); }, });
Cependant, pour la production, je ne souhaite pas enregistrer ce tableau dans mon bouton sessionStorage
中,然后在每次发出新事件时更新它,而是将该 array
保存在我的数据库中,并且我想调用保存 array
的函数当用户 退出
或用户决定关闭网站时(例如按 X
), une fois dans ma base de données.
La première partie - lorsque l'utilisateur logs out
- 非常简单,我只需在 logout
按钮上添加一个 eventListener
, voici la deuxième partie - lorsque l'utilisateur décide de fermer le site - cela me donne un peu mal à la tête.
Je sais qu'il y en a beforeUnload
事件,但是经过快速搜索后,我清楚地意识到它是不可靠的,所以基本上我正在寻找的是一种可靠的方法来确定用户何时关闭我的网站,以便我可以触发 async函数
会将 array
enregistrés dans ma base de données.
Voici mes réflexions sur la façon d'atténuer le manque de fiabilité des événements
beforeunload
:sessions
数组中的当前条目数。假设我们正在讨论您希望重播的单个页面,则可以将此计数保存为 JavaScript 变量eventCount
lors du premier chargement de la page. Il serait préférable d'obtenir le décompte à partir d'une table côté serveur au cas où, pour une raison quelconque, la dernière fois que la page a été fermée, elle n'a pas réussi à enregistrer tous les événements enregistrés.N
秒调用一次函数checkEvents
(您必须决定调用此函数的频率)setInterval
方法。此函数将查看当前事件计数(变量newCount
),如果大于当前eventCount
值,则 NavigatorsendBeacon
方法可用于向服务器发送请求,传递所有自上次调用以来添加的事件(即JSON.stringify(sessions.slice(eventCount, newCount))
,并且当请求完成时分配eventCount = newCount
ifnewCount
为 >eventCount
。请注意,当异步sendBeacon
请求运行时,可能会生成新事件,这就是我们更新事件计数的原因使用newCount
而不是sessions
la taille actuelle du tableau.beforeunload
和unload
事件不可靠,因此我们使用visibiltychanged
事件(如果浏览器支持),当新的可见性状态为“隐藏”时,我们会更新服务器。该文档讨论了导致触发此事件的用户操作(不仅仅是在关闭页面时)。但是,如果浏览器不支持此事件,则 pagehidebeforeunload etvisibiltychanged
🎜. 🎜 🎜 La documentation de la méthode 🎜🎜Navigator.sendBeacon🎜 n'indique pas s'il peut y avoir plusieurs requêtes simultanées. En supposant que cela soit possible (il s'agit d'un appel asynchrone), l'utilisateur peut décider de quitter la page ou de la fermer en raison du 🎜setInterval alors que la requête 🎜sendBeacon🎜 est actuellement en cours. transfert. Ensuite, l'URL du serveur sur lequel vous publiez cette demande devrait probablement verrouiller la table lors de l'exécution de l'insertion, de sorte que tout POST ultérieur sur cette URL soit bloqué jusqu'à la fin du précédent. Si votre table utilise une sorte de numéro de séquence comme clé primaire, une autre solution que je suggérerais serait de transmettre l'index du tableau de départ du premier événement transmis au serveur, et le serveur l'utilisera pour définir explicitement la séquence de chaque événement. Non .insérer un événement. Des mises à jour simultanées peuvent alors être exécutées sans verrouiller la table entière. 🎜Navigator.sendBeacon
方法的文档中没有讨论是否可以有多个并发请求。假设可能存在(这是一个异步调用),则在sendBeacon
(si le navigateur le supporte), nous mettons à jour le serveur lorsque le nouvel état de visibilité est "caché". La documentation traite des actions de l'utilisateur qui provoquent le déclenchement de cet événement (pas seulement lors de la fermeture de la page). Cependant, si le navigateur ne prend pas en charge cet événement, le
pagehide