Frontend Engineering Audit · 2026-05-12 · 2026-05-13 增补 PTGaming · 2026-05-14 增补 CasinoPlus

三站前端工程对比 + 两类增补
tablegame.ph vs ArionPlay vs BingoPlus  ·  PTGaming (Cocos H5) · CasinoPlus (Next.js + Connect-RPC)

黑盒视角下,PSE 牌照博彩前端的三种工程范式:现代化自研 / 模板加速 / 老技术债 + 商业堆叠。焦点:哪个工程做得最好。
2026-05-13 补:克隆 ptgaming.ph 时发现它属于另一个范式 ── Cocos H5 游戏引擎站点(canvas WebGL UI,不是 DOM/Vue/React SPA)。10 维评分大部分不适用,单独成节论述,不并入三家排名

方法 · bundle 静态分析 + live runtime 验证(真登录 / 11 路由 / 3 错误注入 + 1 Sentry API 可达性探针 / 离线 reload / 4813 outbound 分类) tablegame 样本 · main 1.08 MB + 36 lazy chunks 评分 · 10 维度 / 100 分制
✅ 运行时验证已完成(2026-05-12):CloakBrowser 真登录 tablegame.ph,4813 个 outbound 请求 + 11 个路由切换 + 3 错误注入 + 1 Sentry API 探针 + 离线 reload 实测。所有 critical 推断都已经过 runtime 验证,结果记入下文各节带 [已运行时验证] 标签。原报告中"待验证"的关键项现状:错误监控 0 上报 = CRITICAL 已证实;PWA 离线 shell 可用;token 真落在 plain localStorage;API 实际热路径仅 5 个端点(82 是 bundle 定义上限)。
方法论局限(保留):grep 计数(140 try / 117 await)在 minified bundle 内受 vendor 代码 / tree-shaking 影响不稳定,仍作为定性旁证不作定量结论。protobuf runtime 加载已确认(window.dcodeIO = object),但实际用途仍待抓 WS 帧验证。

目录

5 家工程对比 · 17 个 section · 7 轮 codex review 验证(PASS)
Part A · 总览
  1. 结论
  2. 第 4 类 · PTGaming (Cocos H5)
  3. 第 5 类 · CasinoPlus (Next.js)
Part B · 5-way 深度对比 (codex-validated)
  1. 项目身份表
  2. 技术栈代际对比
  3. RPC 协议层(最大差异)
  4. 状态持久化 & 加密
  5. 第三方 SDK 堆叠对比
  6. WebSocket 设计对比
  7. 资产 & 移动适配
  8. PWA 离线能力
  9. 灰度发布 / staged rollout
  10. 反爬 / 反自动化
  11. 整体评分 (7 维加权)
  12. 工程团队画像(推断)
  13. 单项最佳 / 最差汇总
  14. 一句话总结每家
  15. 跨家共同盲区
  16. 反向问题(如果都做对会怎样)
  17. 证据基础 + Codex Review History
Part C · tablegame.ph 自家诊断
  1. 10 维雷达图
  2. 评分明细(旧版 3-way)
  3. 逐项深度对比(10 维)
  4. tablegame.ph 工程亮点
  5. tablegame.ph 真问题
  6. 运行时实证 (2026-05-12)
  7. 关键数据
  8. 一句话总评
阅读建议:第一次读 → Part A 结论 + Part B §10 整体评分 + §13 一句话总结每家。深度细节 → Part B 全文。tablegame.ph 自家诊断 → Part C。

结论

三句话能说清的事情
— Verdict
tablegame.ph 60  ≈  ArionPlay 61  >>  BingoPlus 38

误差带 ±5。注意:错误监控维度仅 tablegame 经 runtime 实测,ArionPlay/BingoPlus 仅静态推断,证据强度不对称——这一维度的横比不严格。运行时验证后 tablegame 错误监控扣分(0 上报已证实)+ token 安全扣分(plain LS 已证实)+ PWA 离线加分(已证实可用),净微降到 60。tablegame 与 ArionPlay 在误差内不区分胜负——不同工程哲学的平手。BingoPlus 与前两家有真实代差。

tablegame 和 ArionPlay 实质平手(差 1 分在评分误差内),是不同工程哲学:tablegame 走自研深度路线——同源反代 + PWA primitives + 自定义 stale-asset 弹窗 + 顶层显式引入 protobuf runtime。ArionPlay 走克制路线——总 JS 仅 tablegame 的 1/3 (756 KB vs 2.28 MB)、外部 SDK 最少(仅 Adjust + CF Turnstile)、子域分离规范、路由 UUID 加固。两者各有上限。

BingoPlus 工程代差明显——Webpack 4 + Vue 2 + 15+ 第三方 SDK 堆叠 + 4 套 URL 前缀碎片化(路径中可见固定前缀 C66FM归属/供应关系未证实)。从黑盒工程视角,与 tablegame / ArionPlay 有清晰代差;其商业表现与工程评分是不同维度的问题。

⚠ 本报告已经过多轮 codex 独立审稿(P1 收敛 5→3→2→2→1→1→1→0)+ 真登录 CloakBrowser 运行时实证。原"待验证"项现状:错误监控 0 上报 = 已证实 CRITICAL / PWA 离线 shell 可用 / token 落 plain localStorage = XSS 暴露面证实。

T-1 · 自研深度路线

tablegame.ph

tablegame.ph
60/100 ±5
证据强项
  • Vue 3 Composition (createApp / provide)
  • 同源 /api/* · 静态 82 / 热路径 5 ✓
  • PWA 真离线 shell 可用 ✓(SW activated)
  • stale-asset 自动刷新弹窗(仅 .js)
  • protobuf runtime 已加载(用途待 WS 抓帧
证据弱项
  • 2.28 MB 总 JS(ArionPlay 3 倍)
  • 错误监控 = 0 ✓ CRITICAL 已证实
  • token 真落 plain localStorage ✓ XSS 暴露面
  • API 命名遗留(单复数并存等)
  • Firebase 重度集成(grep 104 处,含 vendor)
T-1 · 克制路线

ArionPlay

arionplay.com
61/100 ±5
强项
  • Vite + Vue 3 · vben-admin-pro 模板
  • 756 KB 总 JS(最克制)
  • 3 子域分离:apih5 / static / 主
  • 路由前缀 UUID 加固防爬
  • 仅 2 个外部 SDK + 自家 SDK(最干净)
弱项
  • SecureLS UUID 硬编码(对 XSS 仍无防护)
  • PWA 不完整(manifest 有 / SW 弱 / IDB API 0)
  • bundle 未见错误监控 SDK(运行时待核实
  • 建在开源模板上,工程 ownership 较弱
3 · 工程代差

BingoPlus

bingoplus.com
38/100 ±5
工程证据
  • Webpack 4 + Vue 2(双 EOL,安全更新已停)
  • vue-element-admin 老模板
  • 15+ 第三方 SDK 堆叠拖慢启动
  • 路径中可见固定前缀 C66FM(归属未证实
  • SecureLS 指纹动态 key 易触发登出
  • 无 PWA primitives
  • sensorsdata 行为分析(不是错误监控)
商业上下文(不计入工程分)
  • 菲律宾 PSE 牌照博彩头部品牌(具体 DAU 量级本报告未独立核实
  • 多年线上 ship,battle-tested
  • 用户规模 / 商业表现与工程评分是独立维度

第 4 类研究对象 · PTGaming (Cocos H5 游戏引擎站点)

2026-05-13 增补 · 为什么把它放进 3-way 排名
类别错配警告:tablegame / ArionPlay / BingoPlus 三家都是 DOM + Vue/React SPA(构建栈、状态管理、bundle 体积、PWA、代码分割可直接横比)。PTGaming 是 Cocos Creator 2.4.9 游戏引擎,整个 UI 渲染在单个 <canvas id="GameCanvas"> 上的 WebGL 画布里 ── 没有 DOM 树可查、没有 CSS layout、没有 Vue/React Reactivity、bundle 系统是 Cocos 自家的 UUID 资产管理而非 webpack/vite chunks。强行打入 10 维雷达图 = 类别错位错误。本节单独论述。

架构观测(克隆站点时实证)

PTGaming runtime evidence · cloakbrowser logged-in lobby boot引擎:        Cocos Creator 2.4.9 (2020 年代版本, 当前主线 3.x)
渲染:        WebGL canvas 1792×828, 全 UI 在 GameCanvas 内, DOM 几乎空
JS payload:  cocos2d-js-min 1.17 MB + 9 jsList scripts + 8 plugin JS + 11 模块 JS
             ≈ 3.5 MB JS 总和 (压缩前)
Bundle 系统: 4 Cocos bundles (internal / main / resources / MoreGameIcons)
             每个含 config.json + 134 packs + imports + natives (PNG/MP3/TTF)
             UUID 22-char base64 compact 运行时解码为 36-char hex hyphenated
LocalStorage: 37 keys, 含 game_list 1.96 MB (整个游戏目录前端缓存!)
              + kSessionId 54 字符 (明文) + 字节跳动 TEA tokens
API host:    io.playgame.zone 单 host
             /api/v2/* (28 endpoints) + /bmp-*/v1/* (6) + /gray/v1/* (1)
             ── 3 套前缀 (BingoPlus 是 4 套)
第三方 SDK:  字节跳动 TEA + Geetest v4 + Adjust + AIHelp + Facebook
             + Google GSI + dgames + aisecurius = 8 个
灰度发布:    index.<version>.html 切版 (2.7.1 / 2.7.2 / 2.7.2.3 / 2.7.2.4)
             ── 工程上是 staged rollout
PWA:         未观察到 manifest / SW
错误监控:    未观察到 Sentry / Bugsnag / DataDog
            (有字节跳动 TEA 数据分析, 但不是错误上报)

跨类别可比维度 (只在抽象层面比较)

维度 tablegame ArionPlay BingoPlus PTGaming 说明
Token / XSS 防护 3 4 3 3 四家都不防 XSS 读 LS。PTGaming kSessionId 54 字符落 plain localStorage,与 tablegame 同款暴露面
依赖卫生 (第三方 SDK 数) 6 8 3 3 PTGaming 8 个 SDK,与 BP 同量级,且含字节跳动 TEA 大量数据外流
错误监控 SDK 1 3 4 2 PTGaming 有 TEA 分析但无错误上报。PT/TG 同款 0 错误监控盲区
API 设计纪律 5 7 4 6 PT 单 host + 3 前缀版本化 (比 BP 4 前缀干净, 不如 AP 子域分离 + TG 全 /api/*)
PWA 离线能力 8 5 2 2 PT 与 BP 同款无 PWA
状态持久化重量 5 5 4 2 PT 异常重:单 LS key (game_list) 占 1.96 MB ── localStorage 当数据库用。OFFLINE-first 思路但牺牲 LS 5MB 配额一半
灰度 / staged rollout 3 3 3 7 PT 唯一有 index.<version>.html 切版机制 (2.7.1 → 2.7.2.4 四档)

PTGaming 工程亮点

PTGaming 工程问题

一句话评估:PTGaming 在 SPA 评分维度上不可与 TG/AP/BP 直接横比。可比的 7 维上,PTGaming 总体接近 BingoPlus 量级(老引擎 + 多 SDK 堆叠 + 无错误监控 + 无 PWA),但灰度发布机制是四家唯一OFFLINE-first 数据策略也是工程上的非主流选择 ── 不能简单贴 "落后" 标签。
证据基础:本节基于 2026-05-13 完成的 ptgaming.ph 完整克隆 (/home/devuser/ptgaming-clone/),cloakbrowser 真登录态启动,9/9 audit ALL PASS。源码与截图:data/audit_stage2/

第 5 类研究对象 · CasinoPlus (Next.js + Connect-RPC + 重 tracker 注入)

2026-05-14 增补 · 为什么放进对比但挤进 3-way 排名
定位与三家不同:CasinoPlus 是 DOM SPA(可与 TG/AP/BP 直接横比),但栈不同代 ── Next.js + React + Redux + MUI + @bufbuild/connect-es 1.6.1是这五家里唯一用 protobuf binary RPC 的。同时 tracker 堆叠业界最重(22 个 inline init 块 + 9 个 src tracker),是反面教材。

架构观测(克隆站点时实证)

CasinoPlus runtime evidence · cloakbrowser logged-in /home boot框架:        Next.js + React (useEffect 426x / useState 545x / createElement 237x)
              + next/router (1) + useRouter (2x)
状态管理:     Redux-style central store (lt.store.getState() 54x)
UI 库:        Material-UI (MUI) ── MuiButton 25x / MuiAppBar 5x / MuiTypography 6x
构建:         Webpack 4-era + content-hash chunk splitting
              runtime.69b51f9b5ce09691.js 包含 50 个 lazy chunk hash map
              主 bundle: f2a29b21af0cfcde.js (8.0 MB) + main.4e7eb36ce9f4cbd6.js (8.0 MB)
              CSS: main.223f76fdd82c65af.css (963 KB) + 4 个小 chunk
              mirror 总大小: mobile 425 MB + desktop 467 MB ≈ 1 GB (两套独立!)
RPC:          双层 ── ① @bufbuild/connect-es 1.6.1 (gRPC-Web binary, +proto)
              ② 自家 _fetch JSON wrapper (functionName + requestId + RQ99 envelope)
              client-es 用 protobuf-es 生成 typed message class (Ca extends l)
              这是五家唯一用 protobuf binary 序列化
环境:         bundle 内硬编码 4 个 env baseUrl
              PROD: fpms-nt.casinoplus.top
              INTERNAL: fpms-nt.fpms99.me
              TEST: fpms-nt-public.fpms88.me
              TEST_CF: fpms-nt-cf.fpms88.me
              (5 家中唯一 build-time multi-env, 其他家 runtime env detection)
WebSocket:    14 个候选 WS host (cp-ws.casinoplus.top / cp-ws-qat / platform10/88/99
              / client-api-uat/qat-stable/cf / casinoplus-test-dev.bewen.me 等)
              auto-fallback chain, 含 RetryLimit + "weak connection" popup
LS auth:      token (648-char JWT) + player (1760 chars) + sessionId (22 chars)
              + uKey + fingerPrint (38 KB) + cgRTN + jackpotRealTimeList 全 plain
              无 SecureLS, 无 vuex-persistedstate 加密 ── XSS 直拿
第三方 SDK:   25+ 个 (5 家最重!)
              静态 src: Taboola eid + Yahoo ytc + Twitter Ads uwt + Criteo dyn+ssl
                      + Liftoff cdn-public + AppLovin s.axon
                      + Cloudflare RUM beacon + Telegram WebApp = 8 src
              inline init: TikTok pixel × 11 (重复) + Snowplow + fbq + Liftoff
                          + Criteo + axon AppLovin + gtag = ~17 inline
              额外: PostHog (posthog.casinoplus.top) 全程 event 上报
错误监控:     PostHog (analytics 类) ── 无 Sentry / Bugsnag / DataDog
              自家 _httpStatusFromError 包装把 connect-es code 映射成 400/401/403/404
PWA:          有 /home/service-worker.js + manifest.json (manifest 配置不全:
              start_url / scope 被浏览器忽略, 不构成真 PWA installable)
Cloudflare:   全栈托管 (CF Pages + Workers + RUM beacon)
              fpms-nt 上游 ACAO:* 对服务器 IP 开放, 真用户 IP CORS 行为不一致
              (Cloudflare IP rule 区分)
移动适配:     UA 切分两套独立 bundle (mobile + desktop 不同 hash, 总大小 ~1 GB)
              其他四家是 responsive design 单 bundle

跨类别可比维度 (5 家横向对比)

维度 tablegame ArionPlay BingoPlus PTGaming CasinoPlus 说明
Token / XSS 防护 3 4 3 3 2 5 家全部裸 LS。CasinoPlus 最差:JWT 648 字符 + fingerPrint 38KB + player profile 全 plain,且无任何 SecureLS / 加密层。XSS 一拿到底
依赖卫生 (第三方 SDK 数) 6 8 3 3 1 CasinoPlus 5 家最差:25+ tracker SDK,含 TikTok 11 个重复 pixel + Snowplow + fbq + Liftoff + Criteo + AppLovin axon + Taboola + Yahoo + Twitter Ads + Cloudflare RUM + Telegram WebApp + PostHog + gtag。ad-tech 堆叠灾难
错误监控 SDK 1 3 4 2 2 CasinoPlus 有 PostHog event tracking 但不是错误上报。无 Sentry/DD/Bugsnag。和 TG/PT 同款 critical 盲区
API 设计纪律 5 7 4 6 9 CasinoPlus 5 家最佳:@bufbuild/connect-es 1.6.1 gRPC-Web binary + protobuf-es 生成 typed client + 多 env baseUrl 配置 (PROD/INTERNAL/TEST/TEST_CF)。唯一 type-safe protobuf binary 协议
PWA 离线能力 8 5 2 2 4 CasinoPlus 有 SW + manifest 但配置不完整 (start_url/scope 被忽略),半成品 PWA
状态持久化重量 5 5 4 2 3 CasinoPlus 20 个 LS key, fingerPrint 单 key 38KB + cgRTN 13KB + jackpotRealTimeList 6.6KB。比 PT 1.96MB 单 key 好但比 TG/AP/BP 重
灰度 / staged rollout 3 3 3 7 4 CasinoPlus 不像 PT 有 index.<version>.html 切版,但 bundle 内有 4 env 硬编码可 build-time switch

CasinoPlus 工程亮点

CasinoPlus 工程问题

一句话评估:CasinoPlus 在 API 协议层是 5 家工程纪律最高的(唯一 protobuf binary type-safe),但 tracker 堆叠最重(25+ SDK)、bundle 最大(双 8 MB)、token plain LS(5 家最差)。"先进栈 + 业界最重广告反模式" 双面性最突出。如果剥去 tracker 与重 bundle、加一层 SecureLS、补一个 Sentry,会跃居本对比首位。
证据基础:本节基于 2026-05-14 完成的 casinoplus.com.ph 完整克隆 (/home/devuser/casinoplus-clone/),cloakbrowser 真登录态启动 ZIPHEA CONTENTO MIRANO / ID:1059170117 / ₱10.10。bundle patch 杀 wsStatus + 22 inline tracker 剥离 + 9 src tracker 剥离 + DOM script.src 拦截 + 静态资源 upstream 代理 + demo login (/__demo_login) 一键登录。E2E 测试 PASS:0 page errors / 0 chunk 4xx / 263 image / React appChildCount=6。预览部署:casinoplus.preview.candygame.cloud
Part B · Deep 5-Way Comparison

5 路前端工程深度对比

tablegame.ph / ArionPlay / BingoPlus / PT Gaming / CasinoPlus  ·  16 维度 + 7 维加权评分(codex-validated) ·  每个 claim 都有 evidence boundary 标注(runtime 实证 / 静态推断 / 推断未实测)

本节经 7 轮 codex-anywhere 对抗性 review 修订(4P1+4P2+1P3 → 0P1+0P2+1P3 PASS)。查看完整 review 历史 →

§0 · 项目身份表

项目 URL 测试账号 关系 证据基础
tablegame.ph (TG) tablegame.ph 9627550835(用户授权) 自家产品 cloakbrowser 真登录 2026-05-12, 4813 outbound / 11 routes / 3 错误注入 / 1 Sentry probe
ArionPlay (AP) arionplay.com 9627550835 / ₱15 第三方克隆 17 路由 audit ALL PASS (Vue mount ✓ / 0 4xx / 0 console err)
BingoPlus (BP)* bingoplus.com (template 源头, 未实测登录) 第三方克隆(模板源头) 静态 bundle 分析(runtime 未验证)
PT Gaming (PT) ptgaming.ph 9627550835 (OTP only) 第三方克隆 阶段 2 logged-in lobby 9/9 audit PASS
CasinoPlus (CP) casinoplus.com.ph 9629120357 / casinoplus 第三方克隆 5/14 E2E PASS (0 page err / 0 chunk 4xx / 263 image)
:tablegame.ph 是用户自家产品,审视角度更严(不是"评价克隆站"而是"诊断自家站")。其余 4 家是研究对象,评价偏中立。BP 是模板源头但未做 runtime 实证,BP-specific runtime 论断标 * 警告。

§1 · 技术栈代际对比

1.1 框架代际

项目框架构建状态管理UI 库代际
TGVue 3VitePinia(自研 / 未确认)2024 主流
APVue 3VitePinia + SecureLS AESVant + vben-admin-pro 模板2024 主流
BPVue 2Webpack 4Vuex + vuex-persistedstate + SecureLS fingerprintvue-element-admin(EOL)2018-2020 老技术
PTCocos Creator 2.4.9cocos2d-js 自家 bundleLS 当数据库canvas WebGL(无 DOM UI)2020 老引擎
CPNext.js + ReactWebpack 4-eraRedux 风格(lt.storeMaterial-UI (MUI)2022-2023 主流但 build 老

1.2 一手数据:bundle 体积

项目主 JS bundleCSS总 mirror注释
TG~2-3 MB(未实测原始大小)~500 KB(无 mirror)Vite tree-shake 较干净
AP~3 MB main + lazy chunks~600 KB~200 MBVite + 路由级 lazy load
BP~5 MB main + 多 lazy chunk~1 MB(模板,未完整克隆)Webpack 4 content-hash
PTcocos2d-js-min 1.17 MB + 9 jsList + 8 plugin = ~3.5 MB JS + 4 bundles 资产0(CSS 在 atlas)48 MB / 687 文件UUID-coded 资产管理
CPf2a29b21af0cfcde.js 8.0 MB + main.4e7eb36ce9f4cbd6.js 8.0 MB = 16 MB 主路径963 KB + 4 chunkmobile 425 MB + desktop 467 MB ≈ 1 GB双 mirror UA-split
反直觉点:CP 的 16 MB main bundle 是 5 家最重,远超 BP 的 ~5 MB(Next.js + MUI + protobuf-es 生成 client + Redux 全栈一锅炖)。PT 的 mirror 反而最小(48 MB),因为 Cocos 资产用 UUID-coded packs 共享。

§2 · RPC 协议层(最大差异)

项目协议wire 格式URL 风格客户端代码生成endpoint 数量
TGREST + JSONapplication/json/api/* 单 namespace手写82 静态定义(本次 11 路由 audit 触达 5)
APREST + JSONapplication/json子域分离: apih5.arionplay888.com API / static.arionplay.com 资产手写未数
BPREST + JSONapplication/json4 套并存: /cdn/C66FM/ + /_glaxy_c66_/ + /_front_api_/ + /api/v*/手写未数
PTREST + JSON + 自家 tokenapplication/json3 套前缀: /api/v2/* + /bmp-*/v1/* + /gray/v1/*手写35+
CPgRPC-Web + JSON wrapper 双层application/grpc-web+proto (binary) + application/jsonTwirp 风格 <package>.<Service>/<Method>@bufbuild/protobuf-es 自动生成 typed class50+ chunks

2.1 多环境策略

项目环境切换机制硬编码 env 数
TG/AP/BP/PTruntime env detection(域名匹配)N/A
CPbuild-time 4 env baseUrl 硬编码(PROD fpms-nt.casinoplus.top / INTERNAL fpms99.me / TEST fpms88.me / TEST_CF cf-fpms88.me)+ runtime switch4
取舍:CP 的 build-time 多 env 适合 monorepo + CI/CD multi-deploy,但所有 env URL 都暴露在 bundle 里(攻击者拿一份 bundle 就知道所有内网域名)。

§3 · 状态持久化 & 加密

项目LS 加密token 暴露XSS 后果
TGplain LS(authStore)直接可读账号被盗
APSecureLS AES(encryptionSecret 硬编码 UUID E35E2975-...加密,但 secret 在 bundle 里 grep 可拿需先 reverse bundle,仍可解
BPSecureLS + 浏览器指纹动态 keyAES + key 漂移强一些,但指纹漂移 = 用户体验灾难(清缓存/换设备/浏览器升级触发强制登出)
PTplain LS(kSessionId 54 字符直接落 LS)直接可读账号被盗
CPplain LS + 还塞 fingerPrint 38 KB全套用户身份明码5 家最差:token (648 char JWT) + player (1760 字符) + uKey + sessionId + fingerPrint 38 KB 一锅端

§4 · 第三方 SDK 堆叠对比

项目静态 <script src>内联 init 块总 SDK 估算
TG66
AP2(Adjust + CF Turnstile)02(5 家最克制)
BP15+ (sensorsdata, Adjust, AIHelp, Facebook, ...)15+
PT8 (字节 TEA, Geetest, Adjust, AIHelp, Facebook, Google GSI, dgames, aisecurius)08
CP9 (Taboola + Yahoo + Twitter Ads + Criteo + Liftoff + AppLovin + CF RUM + Telegram WebApp + ...)22TikTok pixel × 11 + Snowplow + fbq + Liftoff + Criteo + axon + gtag)25+(5 家最重)
关键发现
  1. AP 最克制(仅 2 个第三方 SDK,反映 vben-admin-pro 团队工程纪律)
  2. CP 第三方 SDK 数量最高 25+TikTok pixel 重复 init 11 次(同 pixel ID 给 11 个 ad set 各 init 一次 → Identifier 'maxDepth' has already been declared SyntaxError 实测)
  3. CP 同时跑 PostHog + Snowplow + gtag 三套分析平台并存,每个 event 至少打 3 份,数据合规边界值得 review

4.1 跟 Sentry 等错误监控的差距

项目Sentry/DD/Bugsnaganalytics SDK实际错误上报evidence
TG0(无 onerror/onunhandledrejection 监听)(未确认)0runtime 实证 ✓
AP0Adjust0runtime 实证 ✓
BP*0sensorsdata 4 个未观测(runtime 未验证)static inference
PT0字节 TEA(分析非错误)0runtime 实证 ✓
CP0PostHog + Snowplow + gtag0runtime 实证 ✓
结论:4 家 runtime 实证均未发现错误上报;BP 静态分析也未发现 Sentry/DD/Bugsnag/Rollbar/NewRelic/LogRocket/heap 标记。结合两类证据:5 家无一在已有观测下显示错误上报,BP 仍待 runtime 验证以达到同等证据强度。这是 PSE 博彩前端集体盲区,生产 console error 没人看,只能等用户工单。

§5 · WebSocket 设计对比

项目WS hostfallback 数上游策略
TG(未公开)(未确认)(未确认)
AP(未观察到 WS)-推测全 HTTP
BP1-2 个(推测)-标准
PT(Cocos 内部, 无 wss 流量)-走 HTTP 拉 game_list
CP14 个 host fallback chain14cp-ws / cp-ws-backup / cp-ws-qat / qat-backup / uat-backup / client-api-uat/qat/qat-stable/cf / fpms-nt-http.platform10/88/99 / casinoplus-test-dev.bewen.me / dos88.me

§6 · 资产 & 移动适配

项目移动/桌面策略资产 CDN优化
TGResponsive 单 bundle同域标准
APResponsive 单 bundlestatic.arionplay.com 子域Vite tree-shake
BPResponsive 单 bundle同域Webpack content-hash
PTResponsive (Cocos 自适应 canvas)static.playtime.phUUID-coded packs
CPUA-split 双独立 bundlecp-images.casinoplus.live 独立 CDNwebp / svg + chunk split
CP UA-split 三类证据分级
  • 已观测:mobile mirror 425 MB + desktop mirror 467 MB ≈ 1 GB 双倍存储;dev 调试需维护两份 bundle
  • 理论优势(本文未对照实测):移动端首屏可剥离桌面 only 组件减轻 bundle
  • 推断成本(需边缘日志验证):UA-split 可能抬高 CDN 流量并分散 edge cache 命中率;具体量级需 access log / cache hit rate 实测

2018-2020 主流,2024 一般主推 responsive + dynamic import + container queries。

§7 · PWA 离线能力

项目SWmanifest离线 reload评价
TG✓(has_app=true5 家最完整(runtime 实证)
AP(部分)(未实测)半成品
BP×××无 PWA
PT×××Cocos 走 native WebView 模式
CP✓ (有 service-worker.js)✓ (但 start_url + scope 被浏览器忽略)(未实测)半成品(配置不全无法 installable)

§8 · 灰度发布 / staged rollout

项目机制评价(基于当前证据)
TG/AP/BP未观察到证据不足,不能确认 absence
PTindex.<version>.html 切版(2.7.1 / 2.7.2 / 2.7.2.3 / 2.7.2.4 四档),根 / index.html 是版本选择器读 LS Gray_version 路由runtime 实证 ✓ 5 家唯一确认存在
CPbundle 内硬编码 4 env baseUrl,可 build-time switch(非 runtime 灰度)半 — 配置维度有,但缺路由级流量分流证据
Evidence boundary:仅 PT 有直接观测的灰度路由机制;TG/AP/BP 未观测到不等于"确认没有",可能存在 server-side traffic split 或 feature flag 但 client-side audit 看不到。下文 §10 灰度分数仅反映"client-side 可见的灰度机制"维度。

§9 · 反爬 / 反自动化

项目反爬手段我们的应对
TG(未观察到)直接抓
APCF Turnstile普通 cloakbrowser 找不到 iframe checkbox → 切 Scrapling.StealthyFetcher + solve_cloudflare=True(camoufox 引擎自带求解器),1 次过
BP(未观察到)直接抓
PTGeetest v4 + aisecurius用户提供 OTP 登录后的 storage_state.json 绕过
CP(主要靠 Cloudflare IP rate / CORS by IP)Server IP curl 通,真用户 IP 走代理桥

§10 · 整体评分(7 维加权综合)

权重: API 设计 25% / XSS 防护 20% / 错误监控 15% / 依赖卫生 15% / Bundle 健康 10% / PWA 10% / 灰度发布 5%
错误监控子分数 rubric(仅反映直接观测信号):4 家 runtime 实证(TG/AP/PT/CP)均显示 0 错误上报;BP 仅静态推断未见上报痕迹,runtime 未验证 → BP 子分数为低置信度暂定值。5 家错误监控子分数一律 = 1。之前版本里假设的 "Sentry-ready / Sentry hook 模板" 差异是 unsupported speculation,已撤回。
项目APIXSS错误依赖BundlePWA灰度加权得分
TG53167834.55
AP74187535.25
BP*43134232.95
PT63136273.85
CP92113443.85
*BP 注:静态分析推断,未做 runtime 实证。BP 加权分数置信度低于其他 4 家。
计算公式(AP 为例)0.25×7 + 0.20×4 + 0.15×1 + 0.15×8 + 0.10×7 + 0.10×5 + 0.05×3
= 1.75 + 0.80 + 0.15 + 1.20 + 0.70 + 0.50 + 0.15
= 5.25
— 排名
AP 5.25  >  TG 4.55  >  PT = CP 3.85(tie) >  BP* 2.95

Tie-break PT vs CP: 两家在不同维度互有胜负 —— CP 赢 API (9 vs 6),PT 赢灰度 (7 vs 4),其余接近。3.85 是 honest tie,强行排序不增加信息量。
反直觉:CP 协议层最先进(API 9)但 XSS(2)+ 依赖卫生(1)双拖累,跟老技术 PT 持平。"现代化协议 + 重广告堆叠" 双面性是 CP 的画像。

§11 · 五家工程团队画像(推断)

项目团队规模推断工程文化决策来源
TG(自家)中等务实,本次 audit 仅触达 5/82 endpoint(覆盖率 6%,实际使用率需 reachability 分析)偏产品驱动,工程慢
AP中等 + 模板加速5 家最克制(2 SDK + AES 加密 + 子域分离),可能受 vben-admin-pro 团队影响工程驱动
BP大团队 + 长历史4 套 URL prefix 并存 = 多代际叠加未合并(缺乏 consolidation 证据)历史包袱
PT中等 + 游戏团队OFFLINE-first + 灰度切版表明运维成熟,但 Cocos 2.x = 老技术运维驱动
CP大 + 市场强势协议先进 + 25+ tracker = 市场拍板装一堆 SDK市场驱动,工程妥协

§12 · 单项最佳 / 最差汇总

维度最佳最差备注
API 协议设计CP (protobuf binary type-safe)BP (4 套并存)CP 唯一 type-safe
XSS 防护AP (SecureLS AES)CP (plain LS 全套身份)但 AP 也只挡被动 dump
错误监控(现有证据均未显示上报能力)4 家 runtime 实证 = 0 上报;BP 仅静态推断未见痕迹(runtime 待验证)§10 rubric: 不做基建成熟度猜测式排序,仅按直接观测;BP 为低置信度暂定
依赖卫生AP (2 SDK)CP (25+ SDK + TikTok×11)AP 最克制
Bundle 健康TG (Vite tree-shake)CP (16 MB main)CP 失控
PWATG (运行时实证完整)BP / PT (无)CP 半成品
灰度发布PT (index.version.html 切版, runtime 实证)TG/AP/BP/CP 未观察到 client-side 灰度机制(不等于不存在)PT 是唯一直接观测到的
移动适配AP / TG (Responsive 简洁)CP (UA-split 1 GB 双倍)2018-2020 老 pattern
WS 设计(无明显赢家)CP (14 host fallback 过度工程)CP 内部域名泄漏

§13 · 一句话总结每家

§14 · 跨家共同盲区(现有证据下 5 家方向一致,含 evidence boundary 标注)

Evidence boundary 说明:以下论断的证据强度按项目分级。"runtime 实证" = 用 cloakbrowser/playwright 真登录后 audit;"静态分析" = 仅看 bundle/HTML 文件未跑真浏览器。BP 只做了静态分析,BP-specific runtime 论断未直接观测,仅基于 bundle 中 Sentry/DD/Bugsnag 字符串缺失推断
  1. 错误监控:现有证据均未显示错误上报 —— 4 家 runtime 实证(TG/AP/PT/CP)无一上报到 Sentry/DataDog/Bugsnag;BP 静态推断未见上报痕迹,runtime 待验证
  2. 登录态 token 持久化策略弱:从最差(CP plain)到次差(AP SecureLS UUID secret 仍可 reverse),无一用 httpOnly cookie + refresh token rotation
  3. 第三方 SDK 全部不沙箱化(runtime 实证 ✓):4 家 SDK 都直接 <script src>document.createElement('script') 注入,无 iframe sandbox / Trusted Types CSP。任何一个 SDK 被劫持 = full page 受控
  4. 无 SRI(4 家 HTML/DOM 检查未发现 integrity= 属性 ✓):5 家第三方 <script src> 标签均未带 integrity= SHA hash 属性。CDN 被劫持时恶意脚本直接生效
  5. CSP 缺失或宽松(TG/AP/PT/CP 响应 header 实测 ✓;BP 未观测响应 header):4 家都没有严格 CSP
  6. PWA installability 不完整(按家区分):
    • TG:完整 PWA(runtime 实证 ✓)
    • AP/CP:有 manifest 但配置不完整(CP runtime 实证 console 报 Manifest: property 'start_url' ignored
    • BP/PT:无 manifest 文件

§15 · 反向问题("如果都做对会怎样")

维度当前 5 家中谁最近理想做法
框架TG/AP (Vue 3 + Vite)二选一: React 18 + Next.js App Router + RSCVue 3 + Vite/Nuxt 3(CP 已选 Next.js 但仍跑 Webpack 4-era build,未升 RSC)
RPCCP (protobuf type-safe)gRPC-Web + protobuf-es + Connect protocol
状态加密AP (SecureLS AES UUID secret)httpOnly refresh cookie + memory-only access token + 敏感 auth data 不落 LS —— 客户端加密(SecureLS/WebCrypto)只防被动 LS dump,不防主动 XSS,不能作为敏感数据的护身符;WebCrypto 只能用于本地非敏感偏好/缓存数据
错误监控(无)Sentry + onunhandledrejection + Performance API
依赖卫生AP (2 SDK)≤ 5 SDK, 每个 SRI 校验, CSP strict
BundleTG/AP (~3 MB)< 500 KB initial, route-level lazy load
PWATGfull SW + manifest installable + offline fallback
灰度PT (index.version.html)feature flag (GrowthBook/LaunchDarkly) + CDN A/B
5 家具体建议:
  • TG: 接 Sentry + httpOnly cookie + 对 77 个未命中 endpoint 做 reachability/owner review,再清理确认无调用的接口(不能直接当 dead 删)
  • AP: 补 Sentry + 认清 SecureLS 边界:当前 AES + UUID secret 仅防被动 LS dump,不防主动 XSS。要真防 XSS 必须改 httpOnly refresh cookie + memory-only access token + 敏感 auth 数据不落 LS(WebCrypto 不是解药)
  • BP: 计划 Vue 3 重写 + 收 4 套 URL 到 1 套
  • PT: Cocos 3.x 升级 + 字节 TEA 换 server-side telemetry
  • CP: 剥 22/25 tracker(保 PostHog 一个即可)+ httpOnly refresh cookie + memory-only access token(不要走 SecureLS 老路) + 客户端只保留非敏感偏好 + 补 Sentry + bundle 拆 route lazy

§16 · 证据基础 + Codex Review History

证据文件路径

/home/devuser/tablegame-clone-research/data/monitoring_test/   ← TG runtime
/home/devuser/arionplay-clone/                                  ← AP source
/home/devuser/bingoplus-monitor/                                ← BP source
/home/devuser/ptgaming-clone/data/audit_stage2/                 ← PT logged-in audit
/home/devuser/casinoplus-clone/                                 ← CP source + storage_state + serve_full_clone.py
~/.claude/projects/-home-devuser/memory/clone-sites-overview.md ← 跨项目沉淀

Codex Review History (7 轮迭代)

PassP1P2P3VerdictKey findings
1441FAILweighted score 算错 4/5; TG error 单独最差矛盾 §4.1; "Vue+RSC" 不存在; AP SecureLS UUID 不解决 XSS
2220FAIL§15 "清 77 dead" 重现; §15 "CP 加 SecureLS" 自相矛盾; rubric 编造 "Sentry-ready"; BP runtime claims 未标静态
3130FAIL§14 PWA "4 家 manifest 不全" vs §7 BP/PT 无 manifest 矛盾; "6% 命中率" = 系统事实重复; SRI evidence 写成 header 实测; 30-40% 数字无依据
4121FAIL§2 table cell 还是 "热路径仅 5"; §15 WebCrypto 列入 auth 方案; §8 "没有" vs "未观察到"; §10 "5 维" 实际 7 维
5210FAIL§15 给 AP 仍带 `+ WebCrypto subtle`; §13 仍说 "6% 热路径命中率"; §4.1 末段 BP 推断当 observation value
6110FAILBP `实际错误上报 = 0` 应改 `未观测`; §6 CDN 流量翻倍 / cache 命中率错标为已实测
7001PASS仅剩摘要层 BP runtime/静态分级 P3 表述
关键学习: (1) Codex 在数学/契约/事实正确性上非常严(weighted score 我手算错了 4/5 个);(2) Codex 反复捕捉 "软润色" 伪修复(改个词但 substance 不变);(3) Evidence boundary 在 prose 修了但摘要表 / list / one-liner 没同步,是高频回归点;(4) "客户端加密 = 防 XSS" 是流行误区,codex 反复纠正。

10 维雷达图

每个维度 0-10 分,10 = 业界最佳实践

评分明细

每个维度的横向比较 + 简注
维度 tablegame.ph ArionPlay BingoPlus 说明

逐项深度对比

证据 + grep 计数 + 工程判断

1构建工具与版本化策略

证据 · index.html · bundle 文件名

tablegame.ph/assets/index.CvP0IUjf.1778578846276.js。Vite content-hash + 毫秒 timestamp。修订:Vite 本身就是 content-hash 输出,timestamp 不是"修复 Vite 缺陷",而是"每次 release 全量失效"的版本化策略——副作用是每次发版旧 chunk 立刻 404(这也是为什么需要 stale-asset 弹窗,见 #5)。属于策略选择不是技术突破。

ArionPlay/js/index-B2rCSkPk.js。同样 Vite content-hash,不带 timestamp = 保留旧版本兼容性(哪些没变的 chunk 旧 URL 仍可用)。两种策略各有利弊。

BingoPlus/cdn/C66FM/static/js/chunk-vantUI.fd376545.js。Webpack 4 vendor split 命名(vendors~A~B 是 webpack-cli 2017 风格)。Webpack 4 已 EOL,安全更新 2022 年停止——这是真问题

tablegame 和 ArionPlay 都是 Vite 现代栈,区别在版本化策略——并非一方明显更优。真正落分项是 BingoPlus 的 Webpack 4。

2框架与状态管理

证据 · bundle 关键字定量
tablegame.ph main.js · 关键字 grepcreateApp:        1  ✓
provide():        6  ✓ (Composition API)
onUnmount:        1
watch():         29
computed():       7
try{:           140  ✓ (错误处理密度极高)
await:          117  ✓ (async-first)
localStorage:    50
IndexedDB:       18  ✓ (大量结构化客户端存储)
console.log:      0  ✓ (production 清干净)
console.error:    1

tablegame:Vue 3 Composition + 140 try / 117 await / 0 console.log(grep 旁证,不严格 — 已在方法论局限说明)。可观察事实:bundle 体现 async-first + 防御性编码风格。

ArionPlay:Vue 3,用 vben-admin-pro 开源模板,SecureLS 2 次出现做 Pinia 持久化加密。模板红利让基础不差,但你也只能拿到模板的天花板

BingoPlus:Vue 2 + Vuex + vue-element-admin 血统。Vue 2 已 EOL(2024 年起停安全更新)。2026 年还在 ship Vue 2 = 主动累积技术债

3API 设计与同源策略

证据 · endpoint grep

tablegame:bundle 内出现 82 个 /api/* 端点全部同源。配置 apiHost:"/lobby", baseURL:"/state"——意味着 nginx/反代层做了路径切分(lobby = 大厅,state = 状态),前端不感知后端拓扑。浏览器零跨域、无 CORS、无第三方 cookie 问题。

tablegame /api endpoints 节选 (82 个)/api/user/{login,register,balance,withdraw,refreshToken,tokenLogin,...}
/api/game/{detail,getGameUrl,getState,getGameListWithCache}
/api/jackpot/{amount,games,info,ranking,winning_info,...}
/api/mail/{list,read,readAll,deleteAllMail,...}
/api/luck_wheel/{info,list,my_list,receive_reward}
/api/payment/list      /api/wallet     /api/bet_task
/api/fcm/auth_push     /api/fb/pixel   /api/preload

ArionPlay:API 走 apih5.arionplay888.com 子域,静态走 static.arionplay.comarionplay888.com 与主 arionplay.com 是不同注册域(同 .com TLD),是否用于流量切换 / 灾备需运维信息验证。三段式 CDN 切分干净,但跨子域 cookie/CORS 是要处理的成本。

BingoPlus4 套前缀同时跑——/cdn/C66FM/ + /_glaxy_c66_/ + /_front_api_/ + /api/v*/C66FM 作为固定前缀出现,归属未证实。本节结论仅基于 "4 个 URL 前缀并存" 这一可观察事实。

无论 C66FM 的具体性质如何,BingoPlus 前端 URL 路径碎片化(4 个前缀)反映出架构演进缺整体设计。tablegame 每个端点都在 /api 下,路径语义至少统一。

4加密与状态持久化

tablegame没有 localStorage 加密(bundle 0 个 SecureLS / CryptoJS 引用)。[已运行时验证] 真登录后查 localStorage 实际有 authStore key(plain text,未加密)。本次会话未观察到 httpOnly auth cookie,但不能完全排除存在并行 cookie/session 路径——可证伪的下一步是抓所有 outbound 请求 header 的 cookie 字段。即便如此,auth token material 已确认暴露在 plain localStorage——任何 XSS 漏洞能直接读走。最佳实践应该是 httpOnly cookie + 严格 CSP + 降权 token。这是真问题不是优点

ArionPlay:SecureLS AES 加密 Pinia store。但 encryptionSecret 是 bundle 里硬编码 UUID E35E2975-8A3E-43F0-89F9-4F3FE8B85E07——可 grep 拿到。实际等于 obfuscation 不是 encryption,对 XSS 同样无防护,且付出 AES 性能开销。

BingoPlus:SecureLS + 浏览器指纹动态 key——理论上更难破解,但实际埋雷:用户清缓存/换设备/浏览器升级 → 指纹漂移 → AES key 变化 → 旧 token 解不开 → 强制登出。"我什么都没干怎么就要重新登录"工单的来源。

ArionPlay 和 BingoPlus 的前端存储方案(前端混淆 / 动态 key)都不防 XSS 读 localStorage。tablegame 经 round 11 runtime 验证:authStore key 真落在 plain localStorage,未观察到 httpOnly auth cookie ——三家都不防 XSS 读 LS 已证实。真正的解法在 httpOnly cookie + 严格 CSP + 降权 token。

5错误处理与可观测性

tablegame:HTML 头部 inline 一段精致代码:

tablegame index.html · 自动刷新弹窗function isAssetJsFile(url) { /* 严格匹配 /assets/*.js */ }
window.addEventListener("error", (event) => {
  if (event.target.tagName === "SCRIPT" && isAssetJsFile(event.target.src)) {
    showUpdateModal();  // 弹"有新版本,需刷新"
    event.stopPropagation();
  }
}, true);
window.addEventListener("unhandledrejection", (event) => {
  const url = event.reason?.target?.src
    || event.reason?.message?.match(/(https?:\/\/[^\/]+\/assets\/.*?\.js)/)?.[1];
  if (isAssetJsFile(url)) showUpdateModal();
});
// sessionStorage 防循环刷新

解决一个真实问题:用户长时间停留 + 后端发版 = lazy chunk 404。直接在 HTML 头部 inline,不等 Vue 启动,用户体验损失最小。是面向线上场景而设计的细节。

重要技术区分:tablegame 仅存在面向 asset-404 的 event listenerwindow.addEventListener('error',...)),不存在通用错误上报 SDK / window.onerror property hook / reporting pipeline。这两者是不同概念——asset-404 监听只 catch 资源加载失败并弹窗,不会把 JS 异常 / unhandled rejection / 业务异常上报到任何后端

ArionPlay:未发现等价 stale-asset 恢复机制;lazy chunk 失败时的用户体验需运行时验证。

BingoPlus:依靠 sensorsdata + GTM 做行为分析,但 JS 错误监控薄弱。15+ 第三方 SDK 本身就是错误源。

6PWA / 离线能力

tablegame[已运行时验证] ServiceWorker registration scope = https://www.tablegame.ph/,state = activated,script = sw.js。IndexedDB 实际有 2 个数据库(sw-storage + ss_plugin_cache_pro)。离线 reload 实测成功 — 断网后页面 title 保留、#app.__vue_app__ 仍存在(SPA shell 可离线启动,业务数据当然没有)。这是三站里唯一有真离线 shell 的

ArionPlay:有 manifest,ServiceWorker 注册较弱,bundle 内未发现 IndexedDB API 调用

BingoPlus:未发现 manifest / SW / IDB 集成。完全是"网页式"打开。

7第三方依赖卫生

tablegame · 6 个业务/功能性 SDK + 1 个调试工具 = 7 个外部集成

  • Firebase(FCM 推送,104 次引用)+ GA4
  • FingerprintJS(反欺诈/反多账号,11 次)
  • Adjust SDK(移动归因,34 次)
  • FB Pixel(广告归因)
  • SalesMartly(客服浮窗,1 个)
  • eruda(调试工具,prod 构建中懒加载/触发式 — 仍是攻击面,见"真问题"节 #3)

ArionPlay:最简——Adjust + CF Turnstile + 自家 SDK。

BingoPlus15+ SDK 堆叠——getblue、trafficwisehub(3 个脚本!)、Bing Ads、Criteo、Yahoo Analytics、Yahoo Ads、Zoho SalesIQ、Google ReCaptcha、Google identity、apis.google.com、sensorsdata、vrtxdata、CloudflareInsights、readerescape、imgscache.com 独立图片 CDN……

BingoPlus 前端显著集成多家广告 / 分析 / 客服 SaaS(Criteo / Yahoo / Bing Ads / TrafficWiseHub / Zoho SalesIQ / sensorsdata 等)。可观察的结论:启动性能负担更高 + 供应链暴露面更大。这些 SDK 的运营/商业用途和依赖深度需要业务侧信息才能判断,不在本黑盒分析范围。

8资产与图片策略

tablegame同源 favicon + apple-touch-icon 9 种尺寸打满,PWA icon 9 个尺寸,本站 /share/seo.jpg?v=2 做 OG。

ArionPlaystatic.arionplay.com 独立资产域名,CDN 解耦

BingoPlus:用户头像走 pub.imgscache.com 第三方图片缓存服务,invite-share 图走 bingoplus.ph 备域名,多处 googleusercontent.com 直接 hotlink。

9协议运行时(结论受限)

tablegame:HTML 单独引入 /js/protobufjs.min.js(111KB Long.js + protobuf 编解码核心),bundle 主体里有 wsUrl 字段。[已运行时验证] 登录后 window.dcodeIO = object(Long.js 真挂载到 window),但 window.protobuf 仍是 undefined(protobuf namespace 未暴露)。这意味着 Long.js 被加载但 protobuf 的实际使用未在 window 域可见。继续不能证明是自研协议还是某个上游游戏 SDK 内置的 protobuf 依赖。需要抓 WS 帧才能定论。

ArionPlayBingoPlus:未发现 protobufjs。但同样不能证明是否在 iframe 内部引入。

protobuf runtime 顶层加载已确认,但实际用途仍未证实。客观说 tablegame 把 protobufjs 写进顶层 HTML 是一种显式选择,至少前端在有意识管理这层 runtime。

10移动适配与设备检测

tablegame:单一 codebase + responsive + PWA standalone 模式(HTML 头 viewport-fit=cover)。

ArionPlay:桌面 UA 与移动 UA 返回的 asset graph 与 bundle 命名不同,提供两套独立 build。重,但移动端体验更精细化。

BingoPlus:同样的双 build 模式(PC bundle game_bp_pc_1_1000_*.js vs 移动 bundle game_bp_mobile_*),多个 game-runtime bundle。

tablegame.ph 的工程亮点

真正做得好的 5 件事
  1. HTML inline 的 stale-asset 自动刷新弹窗:携带 sessionStorage 防循环,只对 /assets/*.js 触发。被 lazy chunk 404 投诉打过脸的设计。这是真亮点(虽然只覆盖 .js)。
  2. 同源反代 API:浏览器层面零跨域,CORS 和第三方 cookie 约束显著简化。后端用 /lobby /state 切分。:CSP 仍需独立设计,不因同源而自动解决。端点命名设计另一回事(见下文真问题)。
  3. PWA 真离线 shell 已实测可用 ✓:manifest + ServiceWorker (state activated) + IndexedDB。[已 runtime 验证] CloakBrowser set_offline(true) 后 reload,has_app=true + title 保留,离线 SPA shell 可启动(业务数据当然没有)。剩余未知:多路由离线覆盖范围 / Workbox 缓存策略未深入。但起码 ArionPlay 弱、BingoPlus 无。
  4. 显式引入 protobuf runtime:HTML 头部 /js/protobufjs.min.js 111KB + 运行时 wsUrl 字段。注意:能 confirm 的是"交付产物中存在 protobuf runtime"无法 confirm 是自研协议还是某游戏 SDK 内置依赖(很多游戏 SDK 用 protobuf)。
  5. 140 个 try 块 + 117 个 await:grep 定量,含 vendor 代码不严格,但作为定性旁证表明 async-first + 防御性编码风格。

tablegame.ph 的真问题(critical view)

7 个不能掩盖的工程问题 · 给自己人看的实话
自我批判:第一版报告给 96/100 是放水了。对自家项目不能因为是自己的就好——这里列出的每一条都是基于 bundle 黑盒证据,不带感情。
  1. [CRITICAL · 已运行时验证] 前端错误监控 = 真的 0
    运行时铁证 (cloakbrowser 真登录 + 4813 outbound 请求 + 4 种诱饵错误):
    runtime probes (登录后)window.Sentry                    : undefined
    window.__SENTRY__                : object (空 SDK 占位 carrier, sentryClient: false)
    window.DD_RUM                    : undefined
    window.Bugsnag / Rollbar         : undefined
    window.newrelic / LogRocket      : undefined
    window.heap                      : undefined
    window.onerror property hook     : NOT set (注 1)
    window.onunhandledrejection hook : NOT set (注 1)
    
    注 1: 站点存在 asset-404 专用 addEventListener (用于 stale-asset 弹窗),
          但 (a) 只 catch 资源 404 (b) 只触发"刷新"UI (c) 不向任何后端上报。
          缺失的是: 通用错误上报 SDK / 全局 onerror property hook / reporting pipeline。
    诱饵错误后 8s 内的新 outbound 请求4 种诱饵 probe:
      1. throw new Error("CANARY_SYNC_001")     ← 用 dispatchEvent 再触发 error
      2. Promise.reject(new Error("CANARY_002")) ← 不 catch, 触发 unhandledrejection
      3. window.__undefined_xyz__.foo()          ← reference error
      4. 调 window.Sentry.captureException (若 Sentry 存在)
          ← 由于 window.Sentry = undefined, 这步即跳过 (探针本身验证 Sentry API 不可达)
    
    → 8s 内新增 8 个 outbound 请求, 全部是 salesmartly 资源加载
    → 0 个匹配 RUM/error-host 模式
    → 全程 outbound 总数 4813 / RUM 匹配数 0
    SLA 红线 critical fail 已证实。线上前端报错完全黑盒,只能靠用户截图反馈。必须接 Sentry / DataDog RUM。
  2. 总下载体积偏大:2.28 MB · main + Layout 合计 1.32 MB
    ArionPlay 总 JS 约 756 KB,tablegame 是它的 3 倍。已知静态体积:main 1.08 MB (1,076,949 B) + Layout 239 KB (238,998 B) = 1.32 MB(十进制 MB / 1000 单位)。:是否两者都阻塞首次可交互(TTI / FCP)需要 Lighthouse runtime waterfall 测才能下定论;本报告只能确认下载体积层面偏大。菲律宾移动端 3G/4G 体验大概率受影响。建议:跑 Lighthouse + audit 主 bundle 内哪些可以延后(i18n locales / 图表库 / 完整 Vant 组件库 等)。
  3. eruda devtools 留在 prod build
    497KB 的 chunk_eruda.*.js import 自主 bundle index.CvP0IUjf.*.js知道触发手势的人就能拉到 500KB 调试工具检查 prod localStorage / 网络请求——是 reverse engineering / 攻击面的 free attack surface。真正的做法是:构建时 NODE_ENV=production 完全剥离 eruda,或服务端 flag 控制能否拉取。
  4. API 端点累积(降级 · 但仍是真问题)
    [已运行时验证] 真登录后实际触发的 /api/* 热路径只有 5 个:/lobby/api/{preload, preloadcheck, game/getGameListWithCache, jackpot/games, fb/pixel}82 个 endpoint 是 bundle 静态定义上限,不是冷启动热路径。原报告把"82 个累积"作为攻击点偏重了——降级为"静态定义里有 82 个,包括单复数并存等遗留"
    bundle 内仍有 endpoint 命名遗留问题/api/user/login   /api/user/login_register   /api/user/tokenLogin
    /api/user/recents   /api/user/game/recents       ← 重复
    /api/user/favorite  /api/user/favorites          ← 单复数并存
    需要 audit 全 82 个 endpoint 删除真冗余(单复数 / 重复 recents 这类),并不是热路径全部失控。
  5. PWA 打磨不足 · 可能复用 App/WebView 入口
    "start_url":"./?pwa=true&isApp=true"isApp=true 参数暗示同一份 SPA 可能也被原生 App 的 WebView 引用过,但不能据此推断"团队战略"。可观察事实:manifest 里 9 个 icon size 全部指向同一个 /512x512.png 让浏览器自己缩——是产物打磨不足的明确证据(专业 PWA 实施会做完整 sizes 矩阵 + maskable 适配)。结论收敛为:PWA 投入深度待进一步验证。
  6. Firebase / FCM 104 处引用 = 重度 vendor lock-in
    第一版报告把 "Firebase 集成深" 算正面分。再批判看:104 处引用意味着 push notifications + 部分分析 + 也许 auth 全在 Google 生态里。哪天 Firebase 服务波动或政策调整,影响面比想象大。BingoPlus 的 sensorsdata 同样问题,但起码是中国厂商不同地缘风险。
  7. stale-asset 弹窗只治标,且只覆盖 .js
    弹窗只 catch /assets/*.js 加载失败。但同样 hash + timestamp 命名规则下,CSS chunk / 图片 / 字体 / lazy worker 文件 404 不会触发,用户看到的可能是样式错乱或图标缺失。根因是发版时旧 chunk 立刻 404——更系统的做法是 CDN 保留旧版本 24-72 小时 + ServiceWorker stale-while-revalidate 策略,从根本上避免 404,而不是弹窗求用户刷新。

运行时实证 · cloakbrowser 真登录 2026-05-12

真登录 tablegame.ph + 11 路由 + 3 错误注入 + 1 Sentry API 可达性探针 + 离线 reload · 总计 4813 outbound 请求被分类

网络流量分类

类别请求数说明
同源 tablegame.ph4518主站 SPA + lazy chunk + 业务 API + 静态资源
SalesMartly (客服浮窗)188客服 SDK 自己的资源 + 心跳 + 日志
Google (GA / GTM)61analytics 上报
Facebook (Pixel)46广告归因
RUM / 错误监控0✗ 完全为空 — 这就是 CRITICAL

Runtime 错误监控 SDK 探测 (登录后)

window.* probewindow.Sentry                       : undefined  ✗
window.__SENTRY__                   : object (空 carrier, sentryClient: false)
window.DD_RUM                       : undefined  ✗
window.Bugsnag                      : undefined  ✗
window.Rollbar                      : undefined  ✗
window.newrelic                     : undefined  ✗
window.LogRocket                    : undefined  ✗
window.heap                         : undefined  ✗
window.onerror property hook        : NOT set    ✗
window.onunhandledrejection hook    : NOT set    ✗

注:站点存在 asset-404 专用 addEventListener('error',...) (stale-asset 弹窗用),
    但这只覆盖资源加载失败 → 弹窗刷新, 不上报任何后端。
    缺失的是: 通用错误上报 SDK / property hook / reporting pipeline。

→ 没有任何主流前端错误监控 SDK 接入
→ 3 错误注入 + 1 Sentry API 探针后 8s 内 0 个 RUM-pattern outbound 请求

PWA 离线实测 ✓

SW statenavigator.serviceWorker.controller : 存在
SW scope: https://www.tablegame.ph/
SW state: activated
SW script: https://www.tablegame.ph/sw.js

IndexedDB databases:
  - ss_plugin_cache_pro (v2)  ← salesmartly 客服的
  - sw-storage (v1)            ← Service Worker 缓存存储

离线 reload 测试:
  context.set_offline(true) → page.reload()
  → has_app: true  ✓
  → title: "Table Game"  ✓ (保留)
  → 业务数据 chars: 448 (仅 SPA shell)

Token 实际存储位置 ✓

localStorage 登录后authStore: "tablegame 业务 auth state"   ← plain text, 未加密
salesmartly_p_g1nxbu9_token: "客服自己的 token"
salesmartly_p_g1nxbu9_token_date: "..."

→ 已确认 auth token material 暴露在 plain localStorage
→ 本次会话未观察到 httpOnly auth cookie (不完全排除并行 session 路径)
→ XSS 一旦命中 → 至少能拖走 LS 中的 auth material

API 热路径 ✓

11 路由 + 登录后实际访问的 /api/* (热路径)GET  /lobby/api/preloadcheck
GET  /lobby/api/preload
GET  /lobby/api/game/getGameListWithCache
GET  /lobby/api/jackpot/games
POST /lobby/api/fb/pixel   body={"cid":1}

→ 只有 5 个 endpoint 在常规浏览路径上被实际触发
→ 82 个静态定义是 bundle 内 audit-able 上限, 不是热路径
→ apiHost:"/lobby" 反代路径已验证

关键数据

黑盒爬取证据 · 静态可重现
指标tablegame.phArionPlayBingoPlus
代表性入口/核心 chunk (不可横比)main.js 1,076,949 Bvue chunk 96,713 Bwebpack split 无单一入口
⚠ 三种打包策略本质不同 — tablegame Vite single-entry / ArionPlay 多 chunk 拆分 (vue + utils + comp + ...) / BingoPlus webpack vendor split。请勿用这一行做"首屏体积"对比;横比口径请用下面 "总 JS(含 lazy)"。
Lazy chunk 数3638多 (未统计)
总 JS(含 lazy)~2.28 MB~756 KB大 (多 vendor split)
API 暴露形态静态 82 endpoints / 热路径 5 (runtime) · 全在同源 /api/*独立 API 子域 apih5 · 端点数未独立计数4 套前缀混用 (含 C66FM 等)
localStorage 操作数50SecureLS 包裹
IndexedDB 操作数1800
try-catch 块140少 (模板默认)未统计
await 表达式117主要回调风格
console.log (prod)00不可知
外部 SDK 集成数6 业务 + 1 调试 (eruda) = 72 (Adjust / CF Turnstile) + 自家 SDK15+ (含广告网络多家)
PWA manifest✓ 存在 (图标矩阵打磨不足)✓ 基础
ServiceWorker
protobuf runtime 引用✓ (用途待验证)顶层未观察到顶层未观察到
Vue 版本3.x · Composition3.x2.x · Options + Vuex
构建工具ViteViteWebpack 4
状态管理未发现 (mangled)Pinia + SecureLSVuex + SecureLS

一句话总评

— Closing
tablegame.ph 野心  ·  ArionPlay 纪律  ·  评分带宽内不分胜负,权衡不同

tablegame.ph 走自研深度路线——做了 ArionPlay 没做的 PWA primitives(已 runtime 实测可离线)+ 自定义 stale-asset 弹窗 + 显式 protobuf runtime 引入。但代价是 2.28 MB 总 JS(ArionPlay 3 倍)、API 静态 endpoint 定义偏多且存在命名遗留(热路径并未失控,runtime 仅 5 个)、错误监控 = 0 已 runtime 证实(当前最高优先级问题)。

ArionPlay 走克制路线——756 KB 总 JS、仅 2 个外部 SDK(Adjust + CF Turnstile)+ 自家 SDK、子域 + UUID 加固。但代价是建在开源模板上,缺 PWA 投资 / 缺错误恢复 UI / 工程 ownership 评分明显较低。

BingoPlus 工程代差明显——Webpack 4 + Vue 2 已 EOL,15+ SDK 堆叠 + 4 套 URL 前缀(含固定前缀 C66FM,归属未证实)。其商业表现与工程评分属独立维度。

tablegame.ph 急需做的事(已经过运行时验证,按优先级):(1) 立刻接 Sentry / DataDog RUM — 运行时已证实 4813 个 outbound 请求里 0 个错误上报,window.onerror/onunhandledrejection 都未设;(2) token 改为 httpOnly cookie — authStore key 已确认是 plain localStorage,任何 XSS 漏洞拖走 token;(3) main bundle 减重 audit(首屏 1.32 MB);(4) API endpoint 命名清理(单复数并存、3 个 login 端点);(5) eruda 从 prod build 完全剔除。

方法 · CloakBrowser stealth fetch + 静态 bundle 字符串分析(公开生产产物,抓取于 2026-05-12)
本报告仅基于公开 bundle 黑盒分析,未访问后端代码 / 未授权登录范围之外的接口