TRACIO 是一套客户端-服务端识别系统。客户端采集浏览器信号并将其发送到服务端,服务端计算出稳定的访客标识符、运行检测算法,并返回经过丰富化的结果。本节将逐一说明该流水线的各个阶段。
Browser TRACIO Cloud | | |-- Tracio.init({ publicKey }) ---------> | (init, no network) | | |-- tracio.getResult() ----------------> | | 1. Collect 130+ browser signals | | 2. Encrypt (XOR + deflate + B64) | | 3. POST to ingress endpoint | | | | |-- Decrypt & extract signals | |-- Compute visitor ID (MurmurHash3-128) | |-- Run bot detection (weighted scoring) | |-- Run smart signals (server-side enrichment) | |-- Run IP intelligence (VPN/proxy/Tor) | |-- Store visit event | | |<-- JSON response ------------------- | | visitorId, confidence, | | bot detection, smart signals | | | |-- Store visitor cookie (_vid_t) -----> | (365-day persistence)当 tracio.getResult() 被调用时,客户端会采集 130 多个不同的浏览器信号,这些信号按层级(tier)组织。采集过程采用多阶段流水线,并借助 Web Worker 和共享 iframe 来提升性能。
| 类别 | 信号数量 | 示例 |
|---|---|---|
| Canvas 与 WebGL | 9 | Canvas 指纹、WebGL 渲染器、WebGL 参数、WebGPU |
| 音频 | 3 | AudioContext 指纹、基础延迟、DRM 时序 |
| 字体与渲染 | 10 | 字体检测、字体偏好、MathML、Emoji 渲染 |
| Navigator 与平台 | 25 | User-Agent、语言、屏幕、硬件并发数、时区 |
| 存储与 Cookie | 10 | localStorage、sessionStorage、Cookie、存储配额 |
| CSS 与媒体查询 | 10 | 配色方案、HDR、减弱动态效果、强制颜色 |
| 网络与 WebRTC | 3 | TURN 探测、连接 RTT、应用版本 |
| 机器人检测 | 15 | Webdriver 标志、自动化框架、eval 长度 |
| 篡改检测 | 8 | 属性 getter 自省、原型链、原生函数完整性 |
| 自定义扩展 | 14 | 数学指纹、架构检测、WASM 特性 |
采集流水线分四个阶段运行,以尽量减少对主线程的阻塞:
阶段 1(立即执行):优先级高且采集速度快的信号(navigator 属性、屏幕、时区)。TURN 探测也在此处启动,因为它是并发运行的。
阶段 2(空闲回调):受益于空闲时段的同步信号(CSS 媒体查询、存储探测、Cookie 测试)。
阶段 3(异步):需要异步 API 或渲染的信号(Canvas、WebGL、音频指纹、字体检测、Emoji 渲染)。
Web Worker:在专用线程中进行隔离式信号采集(WASM 特性检测、doNotTrack)。
系统会一次性创建一个共享的隐藏 iframe,并由多个采集器复用(Emoji、MathML、系统颜色、字体、屏幕帧),从而避免为每个信号单独创建 iframe 带来的开销。
每个信号都遵循统一的结构:
interface Signal<T> { s: number // Status code v: T // Value (when successful)}状态码:
| 状态码 | 含义 |
|---|---|
0 | 成功 |
-1 | 不可用(属性为 undefined) |
-2 | 二次校验失败 |
-3 | 意外行为 |
-4 | 超时 |
-5 | 已禁用 |
-6 | 被 CSP 阻止 |
-7 | 安全错误 |
采集到的信号会先序列化为 JSON,然后在传输前进行加密和压缩:
JSON 序列化:所有信号值都被打包进一个以信号为键的 JSON 对象中,并附带元数据字段(c 表示 API 密钥,t 表示标签,lid 表示关联 ID)。
压缩:如果载荷超过 1024 字节,则使用 CompressionStream("deflate-raw") 进行压缩。
XOR 加密:载荷被封装进一个加密信封中:
Base64 编码:加密后的载荷经过 Base64url 编码,并作为 POST 请求体发送。
请求会发送到 ingress 端点,并携带表示客户端版本和 API 密钥的查询参数。请求包含 CORS 凭据,以便发送第一方 Cookie。
服务端接收加密后的载荷,并通过多个子系统对其进行处理:
服务端解码 XOR 信封,必要时进行解压,并解析 JSON 信号数据。每个信号的状态码和值都会被提取并校验。
访客 ID 采用**分层哈希(tiered hashing)**方法计算(V3):
Tier 1 (Frozen): 20 base62 characters - Stable hardware signals that rarely change - Canvas, WebGL renderer, audio fingerprint, fonts - Provides long-term visitor identity
Tier 2 (Semi-stable): 10 base62 characters - Signals that change with browser updates - User-Agent data, Client Hints, plugins - Extensible without breaking Tier 1
Tier 3 (Volatile): 10 base62 characters - Signals that change frequently - Screen resolution, timezone, language - Used for confidence scoring, not identity每个层级提取其指定的信号,构建一个规范化字符串,并使用 MurmurHash3-x64-128 对其进行哈希。三个层级的哈希值被拼接起来,并以 base62 编码,从而生成最终的访客 ID。
置信度得分(0.0 到 1.0)表示系统对该访客已被正确识别的确信程度:
_vid_t Cookie 匹配,则置信度为最大值。机器人检测引擎会运行多个检测器,其加权输出被组合为一个机器人得分(阈值:bot ≥ 0.70,suspicious ≥ 0.30;一个硬失败信号会直接判定为机器人)。参与评分的检测器包括:
服务端丰富化信号由原始信号数据和 IP 情报计算得出。这些信号包括 VPN/代理/Tor 检测、IP 地理定位、浏览器篡改分析以及可疑度评分。
IP 情报子系统提供:
服务端返回一个 JSON 响应,其中包含:
{ "visitorId": "X7fh2Hg9LkMn3pQr", "bot": { "detected": false, "confidence": 2, "reasons": [] }}这就是 tracio.getResult() 在浏览器中解析出的结果。完整且经过丰富化的事件——包括规范化的 bot_result(human / bot / uncertain)、地理定位以及智能信号——通过 webhooks 在服务端交付,并在仪表盘中呈现。
客户端会将访客令牌同时存储在第一方 Cookie(有效期 365 天,SameSite=Lax)和 localStorage 中,以实现跨会话的持久化。
| 步骤 | 位置 | 耗时 | 描述 |
|---|---|---|---|
| 1 | 浏览器 | ~5ms | 初始化探针,创建共享 iframe |
| 2 | 浏览器 | ~50-150ms | 采集 130 多个信号(并行、多阶段) |
| 3 | 浏览器 | ~5ms | 加密并压缩载荷 |
| 4 | 网络 | ~10-50ms | POST 到服务端 |
| 5 | 服务端 | ~5-20ms | 解密、提取信号、计算访客 ID |
| 6 | 服务端 | ~5-15ms | 运行机器人检测和智能信号 |
| 7 | 服务端 | ~5ms | 构建响应 |
| 8 | 网络 | ~10-50ms | 返回 JSON 响应 |
| 9 | 浏览器 | ~1ms | 存储访客 Cookie |
总往返时间:通常为 80-300ms,具体取决于网络状况和浏览器能力。