Skip to content

高级用法

除了主入口 load() / get(),库还导出了大量「子源」函数,可以独立调用做风控信号或自定义指纹组合。

子源单独调用

函数返回值说明
getUnstableCanvasFingerprintCanvasFingerprint直接渲染 canvas 取 toDataURL hash,不含 Safari/Firefox 反指纹分支处理
getUnstableAudioFingerprintnumber | (() => Promise<number>)OfflineAudioContext 渲染后取波形 hash
getUnstableScreenResolution[number, number] | undefined原始 screen.width × height(已做字符串转数字 + sort)
getUnstableScreenFrame() => Promise<FrameSize>可用屏幕区域的边距(top/right/bottom/left)
getUnstableHardwareConcurrencynumber | undefinednavigator.hardwareConcurrency,已修正字符串场景
getWebGLContextWebGLRenderingContext | undefined复用上游缓存逻辑创建 webgl context,便于自取参数

名字带 Unstable 是有原因的

这些函数不在语义化版本保护内——上游可能在小版本里改返回值结构。如果你打算用作 visitor id 的输入,建议把版本号一起 hash 进去,避免升级后大面积失配。

ts
import {
  getUnstableAudioFingerprint,
  getUnstableCanvasFingerprint,
  getUnstableScreenResolution,
} from '@tripo3d/fingerprint';

const audio = await Promise.resolve(getUnstableAudioFingerprint())
  .then(v => (typeof v === 'function' ? v() : v));
const canvas = getUnstableCanvasFingerprint();
const resolution = getUnstableScreenResolution();

浏览器/引擎判定

函数语义说明
isAndroid() => boolean判断是否 Android(基于多个 UA + DOM 探针)
isChromium() => booleanBlink 内核(含 Edge / Samsung / Brave)
isWebKit() => booleanSafari 内核(mobile + desktop)
isGecko() => booleanFirefox / Tor Browser
isDesktopWebKit() => boolean桌面 Safari(区分 iOS Safari)
isSamsungInternet() => booleanSamsung Internet(基于 Chromium 但行为差异大)
isTrident / isEdgeHTML() => boolean老 IE / 老 Edge 检测
ts
import { isChromium, isSamsungInternet } from '@tripo3d/fingerprint';

if (isChromium() && isSamsungInternet()) {
  // 走 Samsung Internet 的特殊处理
}

hashComponents

任意 UnknownComponents → 32 位 hex hash。

ts
import { hashComponents } from '@tripo3d/fingerprint';

const myComponents = {
  ua: { value: navigator.userAgent, duration: 0 },
  tz: { value: Intl.DateTimeFormat().resolvedOptions().timeZone, duration: 0 },
};

const id = hashComponents(myComponents);

底层用 MurmurHash3 x64 128,对 components 做规范化字符串后取 hash。导出别名 murmurX64Hash128 也可以直接用:

ts
import { murmurX64Hash128 } from '@tripo3d/fingerprint';
murmurX64Hash128('hello world'); // → 32 位 hex

自定义 sources

ts
import { hashComponents, loadSources, prepareForSources } from '@tripo3d/fingerprint';

await prepareForSources(); // 等一帧空闲,保证渲染稳定

const getComponents = loadSources(
  {
    // 你自己的 source 字典:每项都是 () => MaybePromise<value>
    customSignal: () => fetch('/api/risk-signal').then(r => r.text()),
    isLoggedIn: () => Boolean(localStorage.getItem('token')),
  },
  { cache: {}, debug: false },
  [], // 排除列表
);

const components = await getComponents();
const id = hashComponents(components);

componentsToDebugString

把 components 转成可读 JSON 字符串,方便日志:

ts
import { componentsToDebugString } from '@tripo3d/fingerprint';

console.log(componentsToDebugString(components));

错误源会被序列化为 { name, message, stack },避免 JSON.stringify Error 时丢失字段。

withIframe

库内部用来创建隐形 iframe 测量字体。也对外导出:

ts
import { withIframe } from '@tripo3d/fingerprint';

const result = await withIframe(async (iframe, iframeWin) => {
  // 在干净的 iframe context 里做测量
  return iframeWin.document.body.offsetWidth;
});

完整导出清单

ts
// 主 API
export { load, hashComponents, componentsToDebugString }
export type { Agent, LoadOptions, GetOptions, GetResult, Component, UnknownComponents, BuiltinComponents, Confidence }

// 子源(带 Unstable 前缀,不在 SemVer 内)
export {
  getUnstableAudioFingerprint,
  getUnstableCanvasFingerprint,
  getUnstableHardwareConcurrency,
  getUnstableScreenFrame,
  getUnstableScreenResolution,
  getWebGLContext,
}

// 浏览器/引擎判定
export {
  getFullscreenElement,
  isAndroid, isTrident, isEdgeHTML,
  isChromium, isWebKit, isGecko,
  isDesktopWebKit, isSamsungInternet,
}

// 内部工具
export const murmurX64Hash128 = x64hash128
export { prepareForSources, sources, loadSources, transformSource, withIframe }
export type { Source, SourcesToComponents, UnknownSources }

完整签名见 API Reference

基于 MIT 协议发布(内部使用)