我正在嘗試為網站建立使用者重播會話功能,並且我正在使用 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 都會阻塞,直到前一個完成。如果您的表使用某種序號作為主鍵,我建議的另一個解決方案是將傳遞的第一個事件的起始數組索引傳遞給伺服器,並且伺服器將使用它來明確設定每個事件的序列號插入事件。然後可以運行並發更新,而不必鎖定整個表。