快速上手
@tripo3d/fingerprint 暴露的核心 API 只有两个:load() 创建 agent,get() 取指纹。
完整流程
ts
import FP from '@tripo3d/fingerprint';
const fp = await FP.load({
delayFallback: 50, // 不支持 requestIdleCallback 时的 setTimeout 兜底,单位 ms
debug: false, // 控制台打印调试信息
});
const result = await fp.get();
// ^? GetResult为什么 load() 是异步的
load() 内部用 requestIdleCallback(Safari/老 Edge 走 setTimeout 兜底)等待一个空闲帧,以保证 Canvas、WebGL、字体测量等特征渲染完成后再取,避免首帧噪声。这一步是上游推荐的稳定化做法。
LoadOptions
| 字段 | 类型 / 默认 | 说明 |
|---|---|---|
delayFallback | number / 50 | 不支持 requestIdleCallback 时的 setTimeout 兜底毫秒数。仅 Safari 与老 Edge 用得上 |
debug | boolean / false | 在控制台打印 visitorId、components、耗时等调试信息,便于排查 |
上游 monitoring 字段已删除
本副本物理移除了 monitor() 函数与 LoadOptions.monitoring 字段,调用方传入会被 TS 编译期拒绝。详见 NOTICE.md。
GetResult
| 字段 | 类型 | 说明 |
|---|---|---|
visitorId | string | 32 位十六进制 visitor id(MurmurHash3 x64 128 of components canonical string) |
confidence | { score: number; comment?: string } | 0~1 的置信度评分。Android 0.4、Safari 0.3-0.5、Windows 0.6、Mac 0.5、其他 0.7 |
components | BuiltinComponents | 全部特征源采集结果(出错的源带 error 字段)。属于 SemVer 之外,主版本内可能变更 |
version | string | 当前包版本号(来自 package.json,会随我们的发版变化,不等于上游版本) |
典型用法
1. 单纯做 visitor 去重
ts
import FP from '@tripo3d/fingerprint';
const fp = await FP.load();
const { visitorId } = await fp.get();
// 写入 localStorage 兜底,避免每次都重算
let stored = localStorage.getItem('vid');
if (!stored) {
stored = visitorId;
localStorage.setItem('vid', stored);
}2. 调试时打印完整 components
ts
const fp = await FP.load({ debug: true });
await fp.get();
// 控制台会输出 markdown 代码块,含 userAgent、各特征源结果、耗时3. 自定义 hash(不用内置 visitorId)
ts
import { hashComponents, load } from '@tripo3d/fingerprint';
const fp = await load();
const { components } = await fp.get();
// 比如想剔除某些不稳定的源再 hash
const stableComponents = { ...components };
delete (stableComponents as any).fonts; // 字体在某些环境波动大
const myVid = hashComponents(stableComponents);components 长什么样
每一项的形态都是 { value: T, duration: number } 或 { error: ErrorObject, duration: number }:
jsonc
{
"fonts": { "value": ["Arial", "Helvetica", /*...*/], "duration": 12 },
"audio": { "value": 35.7, "duration": 23 },
"canvas": { "value": { "geometry": "data:image/png;...", "text": "...", "winding": true }, "duration": 8 },
"webgl": { "value": { /*...*/ }, "duration": 5 },
"platform": { "value": "MacIntel", "duration": 0 },
"screenResolution": { "value": [1920, 1080], "duration": 0 },
"timezone": { "value": "Asia/Shanghai", "duration": 1 },
// ...
}完整字段清单见 API Reference - BuiltinComponents。
SSR 注意
@tripo3d/fingerprint 只能在浏览器环境调用,包内部直接读 window、document、navigator、screen 等。
在 Nuxt / Next 里:
ts
// ❌ 错:SSR 阶段会爆 ReferenceError: window is not defined
const fp = await FP.load();
// ✅ 对:仅客户端调用
if (import.meta.client) {
const fp = await FP.load();
const { visitorId } = await fp.get();
}下一步
- 高级用法 — 单独导入子源做信号采集
- 商业化投放接入 — 合规 + 归因方案
- Playground — 在浏览器里实测