前端如何设计一个回溯用户操作的方案
同一个项目,为什么我本地无法复现,只有客户的设备才复现?
如何获取用户的操作路径呢?
两种方案:埋点和rrweb
埋点就很简单了,将所有可能操作的节点都进行预埋数据;但埋点简单并不省心(可能会漏掉某个场景)。接下来我们重点探讨rrweb方案。
rrweb
一、录制端(用户端)
1. 获取用户信息
import { getInstance } from "./instance"
let token = ''
export const getToken = () => {
if (token) {
return token
}
const tokenFromSession = sessionStorage.getItem('token')
if (tokenFromSession) {
token = tokenFromSession
return tokenFromSession
}
const inst = getInstance()
const tokenFromInst = inst.getToken()
if (tokenFromInst) {
token = tokenFromInst
return tokenFromInst
}
const __options = inst.getOptions()
const { token: tokenFromOption } = __options
if (tokenFromOption) {
token = tokenFromOption
return tokenFromOption
}
}
2. 用户信息换录制配置
a. 配置为空,退出录制,结束流程
b. 有配置数据,进行第3步
3. 从接口中解析配置数据(获取起始时间点,结束时间点,录制时长)
4. 当前时间点校验(【起始时间,结束时间】)
const { id, singleLength, startTime, endTime } = data
userConfig = { id, maxTime: singleLength, startTime, endTime }
const nowTime = Date.now()
if (nowTime < startTime || nowTime > endTime) {
console.log('[未命中配置]-时间未生效')
return
}
5.开始录制,并存储数据
function record() {
return rrweb.record({
checkoutEveryNth: 100,
emit(event, isCheckout) {
if (isCheckout) {
// 保存数据
saveEvents()
events = []
}
// 临时存储
events.push(event)
},
})
}
6. 超出录制时长,立刻停止,并上报数据
// 停止录播 - 时间限制
sumSecondTimeout = setTimeout(() => {
// 停止录播
stopRecord()
}, maxTime * 60 * 1000)
// 上报数据
http(
'url',
{
jsonListObject: events, // 事件数据
},
{
headers: {
'X-Phone': userPhone,
},
}
)
二、回溯端(B端)
1. 根据手机号获取用户的录制数据(events)
2. 引入rrweb播放端
import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
new rrwebPlayer({
target: videoRef.current, // 可以自定义 DOM 元素
// 配置项
props: {
events,
},
});