使用rrweb 進行web 操做錄製以及回放

rrweb 是使用typescript 開發的web 操做錄製以及回放框架,包含了比較完整的系統組件css

  • rrweb-snapshot 進行dom 與操做實踐的關聯處理
  • rrweb 主要包含了record 以及replay
  • rrweb-player rrweb 的UI 提供了方便的基於UI的操做,好比暫停,時間段選擇

簡單使用

使用docker-compose 運行,同時使用openresty提供了一個簡單的rest api(就是request 以及response沒有具體的存儲操做)html

  • docker-compose 文件
version: "3"
services: 
 app: 
 image: openresty/openresty:alpine-fat
 ports:
 - "8080:8080"
 volumes:
 - "./nginx_lua/:/opt/app/"
 - "./index.html:/usr/local/openresty/nginx/html/index.html"
 - "./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf"
 
 
  • nginx.conf 配置
worker_processes 1;
user root;
events {
 worker_connections 1024;
}
http {
 include mime.types;
 default_type application/octet-stream;
 sendfile on;
 keepalive_timeout 65;
 root html;
 gzip on;
 lua_package_path '/opt/app/?.lua;;';
 lua_code_cache off;
 lua_need_request_body on;
 real_ip_header X-Forwarded-For;
 real_ip_recursive on;
 server {
 listen 8080;
 server_name localhost;
 charset utf-8;
 ssi on;
 default_type text/html;
 location / {
 index index.html index.html;
 }
 location /api {
 content_by_lua_block {
 require("api/api")()
 }
 }
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 root html;
 }
 }
}
  • 基於openresty 的簡單api

    nginx_lua/api/api.lua 文件nginx

-- 很簡單就是獲取request body,後邊的處理就能夠有好多方法了
local json = require("cjson")
function init()
 ngx.req.read_body()
 local body = ngx.req.get_body_data()
 if not body then
 if ngx.req.get_body_file() then
 return nil, "request body did not fit into client body buffer, consider raising 'client_body_buffer_size'"
 else
 return ""
 end
 end
 local res = {
 code = 1,
 message ="ok"
 }
 ngx.log(ngx.ERR, body)
 ngx.say(json.encode(res))
end
return init
 
  • 集成rrweb 的index.html 頁面

    代碼很簡單,就是點擊git

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 <meta http-equiv="X-UA-Compatible" content="ie=edge" />
 <title>rrweb demo web site</title>
 <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/rrweb.min.js"></script>
 <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/record/rrweb-record.min.js"></script>
 <link rel="stylesheet" crossorigin="anonymous"
 href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css" />
 <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/index.js"></script>
</head>
<body>
 <h1 class="some-title">this is some title for test</h1>
 <input type="button" value="record action" onclick="record()" />
 <br />
 <input type="button" value="replay action" onclick="replay()" />
 <div id="replaycontent">
 </div>
 <script>
 window.events = [];
 function record() {
 rrweb.record({
 emit(event) {
 // 將 event 存入 events 數組中
 events.push(event);
 },
 });
 }
 function replay() {
 new rrwebPlayer({
 target: document.getElementById("replaycontent"), // 能夠自定義 DOM 元素
 data: {
 events,
 },
 });
 }
 // save 函數用於將 events 發送至後端存入,並重置 events 數組
 function save() {
 const body = JSON.stringify(window.events);
 events = [];
 fetch("http://localhost:8080/api", {
 method: "POST",
 headers: {
 "Content-Type": "application/json",
 },
 body,
 });
 }
 // 每 10 秒調用一次 save 方法,避免請求過多
 setInterval(save, 10 * 1000);
 </script>
</body>
</html>
 

啓動&&試用

  • 啓動
docker-compose up -d
  • 效果

 

說明

從目前的使用上還有莫名有一個奇怪的bug,可是仍是一個不錯的開源方案,很值得學習使用下github

參考資料

https://github.com/rrweb-io/rrweb
https://www.rrweb.io/
https://github.com/rongfengliang/rrweb-basic-learningweb

相關文章
相關標籤/搜索