我正在尝试为网站构建用户重播会话功能,并且我正在使用 rrweb 库来做到这一点。
这个库的作用是在记录时:它捕获网页中的所有事件,我可以通过将它们存储在 array
中来保存这些事件,当我想重播会话时,我只需将 array
传递给重播函数,该函数处理会话重播。
目前出于测试目的,我将此数组保存在我的 sessionStorage
中,每次发出新事件时,我都会获取 array
然后将该新事件推送到其中,然后再次将 sessionStorage
保存在我的 sessionStorage
中,如下所示:< /p>
rrweb.record({ emit(event) { const sessions = JSON.parse(sessionStorage.getItem('sessions')) || []; sessions.push(event); sessionStorage.setItem('sessions', JSON.stringify(sessions)); }, });
但是,对于生产,我不想将该数组保存在我的 sessionStorage
中,然后在每次发出新事件时更新它,而是将该 array
保存在我的数据库中,并且我想调用保存 array
的函数当用户 退出
或用户决定关闭网站时(例如按 X
按钮),一次到我的数据库。
第一部分 - 当用户 logs out
- 非常简单,我只需在 logout
按钮上添加一个 eventListener
,这是第二部分 - 当用户决定关闭网站时 - 这让我有些头痛.
我知道有 beforeUnload
事件,但是经过快速搜索后,我清楚地意识到它是不可靠的,所以基本上我正在寻找的是一种可靠的方法来确定用户何时关闭我的网站,以便我可以触发 async函数
会将 array
保存到我的数据库中。
以下是我对如何减轻
beforeunload
事件的不可靠性的想法:sessions
数组中的当前条目数。假设我们正在讨论您希望重播的单个页面,则可以将此计数保存为 JavaScript 变量eventCount
。更好的是从服务器端表中获取计数,以防由于某种原因上次关闭页面时未能成功保存所有记录的事件。N
秒调用一次函数checkEvents
(您必须决定调用此函数的频率)setInterval
方法。此函数将查看当前事件计数(变量newCount
),如果大于当前eventCount
值,则 NavigatorsendBeacon
方法可用于向服务器发送请求,传递所有自上次调用以来添加的事件(即JSON.stringify(sessions.slice(eventCount, newCount))
,并且当请求完成时分配eventCount = newCount
ifnewCount
为 >eventCount
。请注意,当异步sendBeacon
请求运行时,可能会生成新事件,这就是我们更新事件计数的原因使用newCount
而不是sessions
数组的当前大小。beforeunload
和unload
事件不可靠,因此我们使用visibiltychanged
事件(如果浏览器支持),当新的可见性状态为“隐藏”时,我们会更新服务器。该文档讨论了导致触发此事件的用户操作(不仅仅是在关闭页面时)。但是,如果浏览器不支持此事件,则 pagehide 事件。Navigator.sendBeacon
方法的文档中没有讨论是否可以有多个并发请求。假设可能存在(这是一个异步调用),则在sendBeacon
请求当前正在进行时,由于setInterval 的原因,用户可能会决定离开页面或关闭页面。调用。然后,您发布此请求的服务器 URL 可能应该在执行插入时锁定表,以便对该 URL 的任何后续 POST 都将阻塞,直到前一个完成。如果您的表使用某种序列号作为主键,我建议的另一个解决方案是将传递的第一个事件的起始数组索引传递给服务器,并且服务器将使用它来显式设置每个事件的序列号插入事件。然后可以运行并发更新,而不必锁定整个表。