当前位置: 首页 > article >正文

前端如何设计一个回溯用户操作的方案

同一个项目,为什么我本地无法复现,只有客户的设备才复现?

如何获取用户的操作路径呢?
两种方案:埋点和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,
  },
});

用户录制端之所以要设置这么多条件,在于C端设备复杂(性能好坏会影响录制);为了保证用户体验,需要在尽量不干扰用户操作的前提下去录制。


http://www.kler.cn/a/505551.html

相关文章:

  • 浅谈云计算02 | 云计算模式的演进
  • [AI部署-tensorRT] customlayer定义添加过程解析
  • 项目练习:若依管理系统字典功能-Vue前端部分
  • LVGL移植高通点阵字库GT30L24A3W
  • SpringMVC
  • 【初识扫盲】厚尾分布
  • c++ 手写queue循环队列
  • Windows 上的 MySQL 8.4.3 和 WSL(Ubuntu)的 MySQL 8.0.40 之间配置 主从同步
  • linux系统监视(centos 7)
  • 数据结构9——二叉搜索树
  • 使用Struts2遇到的Context[项目名称]启动失败问题解决(Java Web学习笔记)
  • 虚拟线程JDK与Spring Core Reactor
  • 2025windows环境下安装RabbitMQ
  • Frida调试il2cpp的程序打印原生c#对象为json
  • Qt 5.14.2 学习记录 —— 십이 QLineEdit、QTextEdit
  • win32汇编环境,窗口程序中组合框的应用举例
  • 如何将一个数组转换为字符串?
  • 01、kafka知识点综合
  • [Linux]Docker快速上手操作教程
  • LevelDB 源码阅读:如何优雅地合并写入和删除操作
  • 【MySQL学习笔记】MySQL存储过程
  • 通信与网络安全管理之ISO七层模型与TCP/IP模型
  • 计算机后端学习路径(精华版)
  • 仪式感在会员体系建设中的重要性及AI智能名片2+1链动模式S2B2C商城小程序的应用研究
  • 神经网络基础-网络优化方法
  • Lua调用C#