I'm trying to build user replay session functionality for a website, and I'm using the rrweb library to do this.
What this library does is when recording: it captures all the events in the web page and I can save these events by storing them in an array
and when I want to replay the session I just Pass array
to the replay function, which handles session replay.
Currently for testing purposes I am saving this array in my sessionStorage
and every time a new event is emitted I get the array
and then push that new event to which then save sessionStorage
again in my sessionStorage
like this: < /p>
rrweb.record({ emit(event) { const sessions = JSON.parse(sessionStorage.getItem('sessions')) || []; sessions.push(event); sessionStorage.setItem('sessions', JSON.stringify(sessions)); }, });
However, for production, I don't want to save that array in my sessionStorage
and then update it every time a new event is emitted, but instead save that array
in in my database, and I want to call a function that saves the array
when the user exits
or when the user decides to close the site (like pressing the X
button), once to my database.
Part one - when the user logs out
- very simple, I just added an eventListener
on the logout
button, here is the second part - when When a user decides to close the site - this gives me a bit of a headache.
I know there is a beforeUnload
event, but after a quick search it became clear to me that it is unreliable, so basically what I'm looking for is a reliable way to determine when the user Closing my website so I can trigger the async function
will save the array
to my database.
P粉4929595992024-03-22 10:27:35
Here are my thoughts on how to mitigate the unreliability of the beforeunload
event:
sessions
array. Assuming we are talking about a single page that you wish to replay, you can save this count as a JavaScript variable eventCount
. Better would be to get the count from a server side table in case for some reason the last time the page was closed it didn't successfully save all logged events. N
seconds using the window's checkEvents
(you must decide how often this function is called) setInterval
method. This function will look at the current event count (variable newCount
) and if it is greater than the current eventCount
value, the Navigator sendBeacon
method can be used to send a message to the server Send a request, passing all events added since the last call (i.e. JSON.stringify(sessions.slice(eventCount, newCount))
and when the request completes assign eventCount = newCount
if newCount
is > eventCount
. Note that new events may be generated when an asynchronous sendBeacon
request runs, which is why we update the event count using newCount
instead of sessions
the current size of the array.beforeunload
and unload
events are unreliable, we use the visibiltychanged
event (if the browser supports it) when the new one is visible We update the server when the sexual status is "Hidden". The documentation discusses user actions that cause this event to be triggered (not just when closing the page). However, if the browser does not support this event, the <必须使用 code>pagehide event. Navigator.sendBeacon
method does not discuss whether there can be multiple concurrent requests. Assuming it's possible (this is an asynchronous call), the user may decide to leave the page or close it due to the setInterval while the
sendBeacon request is currently in progress. transfer. Then, the server URL you post this request to should probably lock the table while performing the insert, so that any subsequent POST to that URL will block until the previous one completes. If your table uses some kind of sequence number as a primary key, another solution I would suggest is to pass the starting array index of the first event passed to the server, and the server will use that to explicitly set the sequence for each event No. insert event. Concurrent updates can then be run without locking the entire table.