Skip to content

高级用法 ​

CDN 白名单配置文件维护 ​

SDK 启动时会从 configUrl 拉取一份 JSON,判定 URL 上的 utm_source 是否应该上报。 JSON 由运营 / 数据团队维护,改完上传 CDN 即生效,无需发版。

Schema ​

json
{
  "version": 1,
  "killSwitch": false,
  "utm_source": ["baidu", "google", "bytedance"]
}
字段类型必填说明
versionnumber是SDK 仅识别 1,非 1 将 fail-open
killSwitchboolean是全局熔断;true 时 SDK 完全不上报
utm_sourcestring[]是utm_source 白名单(值统一小写)

常见操作 ​

新增渠道:

diff
- "utm_source": ["baidu", "google"]
+ "utm_source": ["baidu", "google", "bytedance"]

临时停用某渠道(不删,方便回滚):

diff
- "utm_source": ["baidu", "google", "bytedance"]
+ "utm_source": ["baidu", "google"]

线上紧急熔断(怀疑上报有问题,先止血):

diff
- "killSwitch": false
+ "killSwitch": true

CDN 部署建议 ​

  • 响应头 Cache-Control: max-age=300, public(5 分钟)。过短会增加 CDN 回源, 过长配置生效慢。出现紧急情况时可以临时改成 max-age=30。
  • 配置 CORS 允许业务域名 GET。
  • JSON 内容紧凑(gzip 后 < 200B),不要塞注释。
  • 建议为不同环境(test / prod)部署不同 URL,业务 runtimeConfig 切换。

不要在 JSON 里塞 utm 之外的扩展字段

当前 schema 故意精简,未来需要扩展(比如加 utm_medium 维度白名单)时再走 version: 2,避免业务方反复升级 SDK 才能识别新字段。

fail-open 与 killSwitch 的区别 ​

场景是否上报
CDN 拉取失败(网络 / 5xx / CORS)✅ 上报(fail-open)
CDN 返回 JSON 但字段非法 / version 不识别✅ 上报(fail-open)
CDN 返回 killSwitch: true❌ 不上报(显式熔断)
CDN 返回 killSwitch: false 但 utm_source 不命中❌ 不上报(白名单生效)
URL 没有 utm_source❌ 不上报(非投放流量)

fail-open 保证 CDN 故障不会拖累投放数据采集;killSwitch 是运营/SRE 主动止血的手段。

自定义 fetch(Nuxt 用 $fetch) ​

fetch 入参用来注入业务侧已有的 HTTP 客户端。这一份 fetch 同时用于 CDN 配置拉取 和 landing 上报:

ts
const trace = new TripoTrace({
  baseUrl:   'https://api-cn-test.tripo3d.com',
  configUrl: 'https://cdn.example.com/trace/whitelist.json',
  fetch:     $fetch.raw, // Nuxt ofetch 实例
});

这样所有请求都会复用 Nuxt 的 baseURL、timeout、错误重试等配置。注意自定义 fetch 必须满足 Web Fetch API 签名(接收 url + init,返回 Response)。

为什么不强制注入 $fetch

库不感知 Nuxt,保留原生 fetch 兜底,让 React/Vite/普通 SPA 等场景也能直接用。

错误处理 ​

ts
const trace = new TripoTrace({
  baseUrl:   '...',
  configUrl: '...',
  onError: (err, ctx) => {
    if (ctx.phase === 'init') {
      // device id 加载失败:可能是隐身模式 + Canvas/WebGL 被禁
      console.warn('[trace] device id 加载失败', err);
    } else if (ctx.phase === 'config') {
      // CDN 白名单拉取失败 / 解析失败:SDK 会 fail-open 继续上报
      console.warn('[trace] CDN 白名单加载失败(已 fail-open)', err);
    } else if (ctx.phase === 'report') {
      // 上报请求失败:网络问题、CORS、5xx
      console.warn('[trace] landing 上报失败', err);
    }
  },
});

库内部不会重试任何失败请求,避免雪崩。失败的 landing 也不会写 dedupe 标记,下次访问同 URL 会重试。

上报成功钩子 ​

ts
const trace = new TripoTrace({
  baseUrl:   '...',
  configUrl: '...',
  onReport: (payload) => {
    // 用于业务侧的链路监控(比如转发到 Sentry / 数据看板)
    myMonitor.track('attribution_landing', payload);
  },
});

钩子在 dedupe 标记写入之后触发,保证幂等:同一 URL 在 1 分钟窗口内只会触发一次。 payload.landing_url 已经包含完整 query string,业务侧可以自行 parse 出 utm 各字段。

SPA 路由变化 ​

库本身只在 landing() 调用时检查一次 entry URL。但 SDK 用的是构造时缓存的 entry URL,不是当次 window.location.href —— 这意味着 SPA 内部跳转后再调 landing(),判定的仍然是用户首次进入站点的 URL:

ts
// Vue Router
router.afterEach(() => {
  trace.landing();
});

这次重复调用的意义在于:

场景行为
首次 init 时 device id 还没解析完成第二次调用补上 landing 上报
首次调用时 CDN 拉取失败不会自动重试(同实例 CDN 只拉一次)
URL 已通过 history.replaceState 改写不影响判定(entry URL 已经缓存)
已经上报过dedupe 命中,不发请求

跨页归因

如果业务方希望「用户点站内链接,进入第二个带 utm 的 URL 时也归因」,这种场景 SDK 不直接支持(一次实例只缓存一次 entry URL)。推荐做法是在第二个页面 reload 或重新 new TripoTrace 一次。

自管 device id(业务自有 ID 体系) ​

如果业务已经有自己的 visitor id(例如登录用户的 user_id 哈希),可以跳过指纹计算:

ts
const userIdHash = await fetchUserIdFromBackend();

const trace = new TripoTrace({
  baseUrl:          '...',
  configUrl:        '...',
  deviceIdOverride: userIdHash,
});

await trace.init(); // 直接用 userIdHash 当 device id
trace.landing();

deviceIdOverride 也会被写入 localStorage,下次访问继续生效。

注意混用风险

deviceIdOverride 一旦写入 localStorage,再次访问时(即便不传 override)也会用缓存值。如果业务的 user id 体系会变(登出/换号),需要业务侧主动清理 localStorage['tripo:device_id']。

直接调用底层工具 ​

库重导出了 fingerprint 的 hash 函数,便于业务做相关 key 计算:

ts
import { murmurX64Hash128 } from '@tripo3d/trace';

const stableKey = murmurX64Hash128(`my-business-${userId}-${context}`);

完整导出清单 ​

ts
// 主类
export { TripoTrace }

// 类型
export type {
  LandingPayload,
  RemoteTraceConfig,
  TraceErrorContext,
  TripoTraceParams,
}

// 底层工具
export { murmurX64Hash128 } // re-exported from @tripo3d/fingerprint

完整签名见 API Reference。

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