Title: JavaScript SDK Locale: zh URL: https://sensorswave.com/docs/data-integration/client-sdks/javascript/ Description: JavaScript SDK 集成指南和 API 参考 Sensors Wave JavaScript SDK 是专为 Web 应用设计的客户端数据采集和 AB 实验工具。 ## 核心功能 JavaScript SDK 提供以下核心能力: - **事件追踪**:手动追踪自定义事件和用户行为 - **自动埋点**:自动采集页面浏览、页面加载、页面离开、点击等事件 - **用户识别**:支持匿名用户和登录用户身份关联 - **用户属性管理**:完整的用户属性操作(设置、追加、增量更新等) - **A/B 测试集成**:支持功能开关(Feature Gate)和实验变量获取 - **单页应用支持**:完整支持 React、Vue、Angular 等 SPA 框架的路由监听 - **批量发送**:优化网络请求性能,每 5 秒批量发送最多 10 个事件 - **公共属性**:支持静态和动态公共属性,自动附加到所有事件 ## 安装 ### NPM 安装(或者 yarn、pnpm 安装) ```bash npm install @sensorswave/js-sdk ``` ### Script 标签引入 如果您的项目不使用构建工具,可以通过 Script 标签直接引入: ```html ``` > **提示**:您可以从 npm 包的 `dist` 目录中获取编译后的文件,或使用 CDN 服务。 ## 快速开始 ### 基础初始化 在您的应用入口文件中初始化 SDK: **ES6 模块方式(推荐)** ```javascript // 初始化 SDK SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com', // 数据上报地址 debug: false, // 调试模式 autoCapture: true // 开启自动埋点 }); ``` **Script 标签方式** ```html SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com', debug: false, autoCapture: true }); ``` ### 发送第一个事件 初始化完成后,您可以立即开始上报事件: ```javascript // 追踪用户点击按钮 SensorsWave.trackEvent('ButtonClick', { button_name: 'submit', page: 'home' }); ``` ## 配置选项 `init` 方法的第二个参数是配置对象,支持以下选项: | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `apiHost` | `string` | `''` | **必填**,数据上报的 API 地址,您可以在 Pipeline 中查看 | | `debug` | `boolean` | `false` | 是否开启调试模式,开启后在控制台输出详细日志 | | `autoCapture` | `boolean` | `true` | 是否开启自动埋点,自动采集页面浏览、加载、离开事件 | | `enableClickTrack` | `boolean` | `false` | 是否开启点击自动追踪(追踪主要的可点击元素) | | `isSinglePageApp` | `boolean` | `false` | 是否为单页应用(SPA),开启后自动监听路由变化 | | `crossSubdomainCookie` | `boolean` | `true` | 是否支持跨子域共享 Cookie(用于跨子域用户识别) | | `batchSend` | `boolean` | `true` | 是否使用批量发送,每 5 秒批量发送最多 10 个事件 | | `enableAB` | `boolean` | `false` | 是否开启 A/B 测试功能 | | `abRefreshInterval` | `number` | `600000` | A/B 测试配置刷新间隔(毫秒),默认 10 分钟 | ### 完整配置示例 ```javascript SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com', debug: true, // 开发环境开启调试 autoCapture: true, // 开启自动埋点 enableClickTrack: true, // 开启点击追踪 isSinglePageApp: true, // 单页应用模式 crossSubdomainCookie: true, // 跨子域共享用户身份 batchSend: true, // 批量发送优化性能 enableAB: true, // 开启 A/B 测试 abRefreshInterval: 10 * 60 * 1000 // A/B 测试数据每 10 分钟刷新 }); ``` > **提示**:在生产环境中建议关闭 `debug` 模式,以避免在浏览器控制台输出过多日志。 ## API 方法 ### 事件追踪 #### trackEvent - 追踪自定义事件 手动追踪自定义事件及其属性。 **参数**: - `eventName` (string,必填):事件名称 - `properties` (Object,可选):事件属性,键值对形式 **示例**: ```javascript // 追踪按钮点击 SensorsWave.trackEvent('ButtonClick', { button_name: 'submit', page: 'home' }); ``` **实际场景示例**: ```javascript // 电商场景:用户浏览商品 SensorsWave.trackEvent('ProductView', { product_id: '12345', product_name: '无线蓝牙耳机', category: '电子产品', price: 299.00, currency: 'CNY' }); // 电商场景:用户加入购物车 SensorsWave.trackEvent('AddToCart', { product_id: '12345', quantity: 1, price: 299.00 }); // 内容平台:文章阅读 SensorsWave.trackEvent('ArticleRead', { article_id: 'article_001', title: 'JavaScript 性能优化技巧', category: '技术博客', read_duration: 120 // 阅读时长(秒) }); ``` #### track - 高级事件追踪 发送完整的事件对象,支持更精细的控制。此方法允许您手动指定所有事件字段。 **参数**: - `event` (AdvanceEvent,必填):完整事件对象,包含以下字段: - `event` (string,必填):事件名称 - `properties` (Record,可选):事件属性 - `time` (number,必填):时间戳(毫秒) - `anon_id` (string,可选):匿名用户 ID - `login_id` (string,可选):登录用户 ID。login_id 和 anon_id 必须传一个,同时传递时,优先使用 login_id - `trace_id` (string,必填):请求追踪 ID - `user_properties` (Record,可选):用户属性 **示例**: ```javascript SensorsWave.track({ event: 'purchaseCompleted', properties: { product_id: '12345', amount: 99.99, currency: 'USD' }, time: Date.now(), trace_id: 'unique-trace-id-12345', anon_id: 'anonymous-user-id', login_id: 'user_12345', user_properties: { // $set: 代表插入或者更新一条用户属性信息 $set: { plan: 'premium', signup_date: '2024-01-01' } } }); ``` > **注意**:`track` 方法是高级功能,大多数场景下使用 `trackEvent` 即可满足需求。 ### 用户识别 #### identify - 设置登录用户 ID 设置登录用户 ID 并发送绑定事件,将匿名行为与已识别用户关联。 **参数**: - `loginId` (string | number,必填):用户的唯一标识符(如邮箱、用户 ID、用户名) **示例**: ```javascript // 用户登录后设置用户 ID SensorsWave.identify('user_12345'); ``` **完整登录流程示例**: ```javascript // 用户登录流程 async function handleUserLogin(email, password) { try { // 调用登录 API const response = await fetch('/api/login', { method: 'POST', body: JSON.stringify({ email, password }) }); const { userId } = await response.json(); // 设置用户 ID 并关联匿名行为 SensorsWave.identify(userId); } catch (error) { console.error('登录失败:', error); } } ``` > **重要提醒**:如果 `loginId` 包含隐私信息(如手机号、邮箱、身份证号等),请务必在加密后再进行传输,避免敏感信息明文上报。 #### setLoginId - 仅设置登录 ID 设置登录用户 ID,但不发送绑定事件。如果您只想识别用户但不需要关联用户,可以使用此方法。 **参数**: - `loginId` (string | number,必填):用户的唯一标识符 **示例**: ```javascript SensorsWave.setLoginId('user_12345'); ``` > **重要提醒**:如果 `loginId` 包含隐私信息(如手机号、邮箱、身份证号等),请务必在加密后再进行传输,避免敏感信息明文上报。 > **使用建议**:通常情况下推荐使用 `identify` 方法,因为它会记录用户身份关联事件,有助于后续分析。 #### getLoginId - 获取当前登录 ID 获取当前已识别用户的登录 ID。 **返回值**:string | number **示例**: ```javascript const loginId = SensorsWave.getLoginId(); console.log('当前登录 ID:', loginId); ``` #### getAnonId - 获取匿名 ID 获取当前用户的匿名 ID。此 ID 是自动生成的,并在会话之间保持持久化。 **返回值**:string **示例**: ```javascript const anonId = SensorsWave.getAnonId(); console.log('匿名用户 ID:', anonId); ``` ### 用户属性 用户属性用于描述用户的特征,如会员等级、注册时间、偏好设置等。与事件属性不同,用户属性会持久化保存并与用户关联。 #### profileSet - 设置用户属性 设置用户属性,如果属性已存在则覆盖。 **参数**: - `properties` (Object,必填):要设置的用户属性 **示例**: ```javascript // 用户完成注册后,设置用户属性 SensorsWave.profileSet({ name: 'John Doe', age: 30, plan: 'premium' }); ``` #### profileSetOnce - 仅首次设置 设置用户属性,仅在属性不存在时设置,已存在的属性不会被覆盖。 **参数**: - `properties` (Object,必填):要设置的用户属性 **示例**: ```javascript // 记录用户首次访问信息(仅记录一次,后续不会覆盖) SensorsWave.profileSetOnce({ signup_date: '2024-01-15', initial_referrer: 'google', initial_campaign: 'spring_sale' }); ``` #### profileIncrement - 增量更新数值属性 对数值类型的用户属性进行增减操作。仅支持数值属性。 **参数**: - `properties` (Object,必填):要增减的属性及其数值 **示例**: ```javascript // 增加单个属性 SensorsWave.profileIncrement({ login_count: 1 }); // 增加多个属性 SensorsWave.profileIncrement({ login_count: 1, points_earned: 100, purchases_count: 1 }); ``` #### profileAppend - 追加到数组属性 向数组类型的用户属性追加新值,不进行去重。 **参数**: - `properties` (Object,必填):要追加的属性及其数组值 **示例**: ```javascript SensorsWave.profileAppend({ categories_viewed: ['electronics', 'mobile_phones'], tags: ['new_customer', 'q1_2024'] }); ``` #### profileUnion - 追加到集合属性(去重) 向数组类型的用户属性追加新值,自动去重。 **参数**: - `properties` (Object,必填):要追加的属性及其数组值 **示例**: ```javascript // 第一次调用 SensorsWave.profileUnion({ interests: ['technology', 'gaming'] }); // 第二次调用,'technology' 不会重复添加 SensorsWave.profileUnion({ interests: ['technology', 'music'] // 只会增加 'music' }); ``` #### profileUnset - 删除指定属性 将指定的用户属性设置为 null。 **参数**: - `propertyNames` (string | string[],必填):要置为 null 的属性名或属性名数组 **示例**: ```javascript // 处理单个属性 SensorsWave.profileUnset('temporary_campaign'); // 处理多个属性 SensorsWave.profileUnset(['old_plan', 'expired_flag', 'temp_id']); ``` #### profileDelete - 删除所有用户属性 删除当前用户的所有用户属性数据。此操作不可撤销。 **示例**: ```javascript // 用户注销账号时,删除所有用户属性 SensorsWave.profileDelete(); ``` > **警告**:`profileDelete` 会删除所有用户属性,请谨慎使用。 #### 用户属性使用示例 **会员升级场景**: ```javascript function handleMembershipUpgrade(newPlan) { // 更新会员等级和升级时间 SensorsWave.profileSet({ plan: newPlan, upgrade_time: new Date().toISOString() }); // 增加升级次数 SensorsWave.profileIncrement({ upgrade_count: 1 }); // 追踪升级事件 SensorsWave.trackEvent('membershipUpgrade', { from_plan: 'basic', to_plan: newPlan }); } ``` ### 公共属性 公共属性会自动添加到所有事件中,适用于需要在每个事件中都包含的通用信息。支持静态属性(字符串值)和动态属性(函数返回值)。 #### registerCommonProperties - 注册公共属性 注册静态或动态公共属性,这些属性将自动包含在所有事件中。 **参数**: - `properties` (Record,必填):要注册的属性 - 静态属性:字符串值 - 动态属性:函数(每次发送事件时调用) **示例**: ```javascript SensorsWave.registerCommonProperties({ // 静态属性 app_version: '1.0.0', environment: 'production', // 动态属性(每次发送事件时调用) current_time: () => new Date().toISOString(), user_session_id: () => getSessionId(), // 用户相关的动态数据 user_tier: () => getUserTier() }); ``` #### clearCommonProperties - 清除公共属性 移除指定的已注册公共属性。 **参数**: - `propertyNames` (string[],必填):要移除的属性名数组 **示例**: ```javascript SensorsWave.clearCommonProperties(['app_version', 'user_session_id']); ``` > **注意**:公共属性会增加每个事件的数据量,建议仅添加确实需要的通用属性。 ### A/B 测试 JavaScript SDK 内置了 A/B 测试支持,可以获取功能开关状态和实验变量。 #### 开启 A/B 测试功能 ```javascript SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com', enableAB: true, // 开启 A/B 测试 abRefreshInterval: 10 * 60 * 1000 // 配置刷新间隔(10 分钟) }); ``` #### checkFeatureGate - 检查功能开关 检查功能开关(Feature Flag)是否为当前用户启用。返回 Promise,解析为布尔值。 **参数**: - `key` (string,必填):功能开关的 Key **返回值**:Promise **示例**: ```javascript // 检查功能是否启用 SensorsWave.checkFeatureGate('new_checkout_flow') .then(isEnabled => { if (isEnabled) { // 显示新功能 showNewCheckout(); } else { // 显示旧功能 showOldCheckout(); } }); // 使用 async/await async function initFeature() { const isEnabled = await SensorsWave.checkFeatureGate('advanced_search'); if (isEnabled) { enableAdvancedSearch(); } } ``` #### getExperiment - 获取实验变量 获取当前用户的实验变量数据。返回 Promise,解析为实验配置对象。 **参数**: - `key` (string,必填):实验的 Key **返回值**:Promise 返回的对象包含实验的变量配置值(Record)。 **示例**: ```javascript // 获取实验配置 SensorsWave.getExperiment('pricing_display') .then(experiment => { if (experiment) { // 应用实验配置 const { price_format, discount_type } = experiment; updatePricingDisplay(price_format, discount_type); } }); // 使用 async/await async function initExperiment() { const experiment = await SensorsWave.getExperiment('pricing_display'); if (experiment) { const { price_format, discount_type } = experiment; updatePricingDisplay(price_format, discount_type); } } ``` **完整 A/B 测试示例**: ```javascript // 电商首页 CTA 按钮 A/B 测试 async function initHomepageCTA() { try { const experiment = await SensorsWave.getExperiment('homepage_cta_test'); if (experiment) { const { button_text, button_color, button_size } = experiment; const ctaButton = document.getElementById('cta-button'); ctaButton.textContent = button_text || '立即购买'; ctaButton.style.backgroundColor = button_color || '#ff6600'; ctaButton.style.fontSize = button_size || '16px'; } } catch (error) { console.error('获取实验变量失败:', error); // 使用默认配置 } } // 页面加载时初始化 initHomepageCTA(); ``` > **提示**:A/B 测试功能需要在 Sensors Wave 后台配置实验和功能开关后才能使用。 ## 自动埋点 开启自动埋点后,SDK 会自动采集以下事件类型: | 事件名称 | 说明 | 触发时机 | |---------|------|---------| | `$PageView` | 页面浏览 | 用户访问页面时 | | `$PageLoad` | 页面加载完成 | 页面加载完成时 | | `$PageLeave` | 页面离开 | 用户即将离开页面时 | | `$WebClick` | 元素点击 | 用户点击元素时(需开启 `enableClickTrack`) | ### 开启自动埋点 ```javascript SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com', autoCapture: true, // 开启自动埋点 enableClickTrack: true // 开启点击自动追踪 }); ``` ### 单页应用(SPA)支持 如果您的应用使用 React、Vue、Angular 等 SPA 框架,需要开启 `isSinglePageApp` 选项: ```javascript SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com', autoCapture: true, isSinglePageApp: true // 开启 SPA 模式,自动监听路由变化 }); ``` SPA 模式下,SDK 会自动监听路由变化并发送 `$PageView` 事件。 > **提示**:自动埋点功能可以大幅减少手动编码工作量,但会增加一定的数据量。建议根据实际需求选择性开启。 ## 框架集成示例 ### React 集成 ```javascript // src/utils/analytics.js SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com', isSinglePageApp: true, // React 是 SPA autoCapture: true }); ``` ```javascript // src/App.js function ProductDetail({ productId }) { useEffect(() => { // 组件加载时追踪事件 SensorsWave.trackEvent('ProductView', { product_id: productId }); }, [productId]); return ...; } ``` ### Vue 集成 ```javascript // src/plugins/analytics.js install(app) { SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com', isSinglePageApp: true, autoCapture: true }); // 挂载到全局属性 app.config.globalProperties.$analytics = SensorsWave; } }; ``` ```javascript // src/main.js const app = createApp(App); app.use(analytics); app.mount('#app'); ``` ```vue const { proxy } = getCurrentInstance(); function handleAddToCart() { proxy.$analytics.trackEvent('AddToCart', { product_id: 'SKU-12345' }); } ``` ## 注意事项 ### 性能优化 - 避免在循环中频繁调用 `trackEvent`,建议合并事件或使用节流 - 批量发送功能默认已开启,可有效减少网络请求 - 自动埋点会增加一定性能开销,仅在需要时开启 ### 数据安全 - 不要在事件属性中传递敏感信息(如密码、信用卡号、身份证号) - Source Token 应妥善保管,避免在公开代码仓库中暴露 - 跨域请求需确保数据上报地址支持 CORS ### 浏览器兼容性 - 支持 Chrome、Firefox、Safari、Edge 等现代浏览器 - 不支持 IE 11 及更早版本 ### 数据丢失风险 - 客户端埋点可能受广告拦截器影响,导致 10-20% 左右的数据丢失 - 核心业务数据建议使用服务端埋点,详见 [埋点方案选择](../tracking-strategy.mdx) - 使用 `beforeunload` 事件追踪页面离开时,部分浏览器可能不会发送请求 ## 常见问题 ### 为什么我的数据没有上报成功? 检查以下几点: 1. **Source Token 是否正确**:确认 `sourceToken` 参数是否正确 2. **数据上报地址是否正确**:确认 `apiHost` 配置是否正确 3. **网络连接**:打开浏览器开发者工具(F12)→ Network 标签,查看是否有请求失败 4. **跨域问题**:确认数据上报地址支持 CORS 5. **广告拦截器**:部分广告拦截器会拦截数据采集请求,尝试关闭后测试 6. **调试模式**:开启 `debug: true` 查看控制台日志 ### 如何避免在开发环境发送数据? ```javascript const isDevelopment = process.env.NODE_ENV === 'development'; if (!isDevelopment) { SensorsWave.init('YOUR_SOURCE_TOKEN', { apiHost: 'https://your-api-endpoint.com' }); } // 封装一个安全的追踪方法 function trackEvent(eventName, properties) { if (!isDevelopment) { SensorsWave.trackEvent(eventName, properties); } else { console.log('[Analytics]', eventName, properties); } } // 使用示例 trackEvent('ButtonClick', { button_name: 'submit' }); ``` ## 相关文档 - [埋点方案选择](../tracking-strategy.mdx):了解服务端埋点和客户端埋点的优劣 - [如何正确的标识用户](../user-identification.mdx):用户身份识别的最佳实践 - [数据模型](../data-model.mdx):理解 Sensors Wave 的数据结构 - [事件和属性](../events-and-properties.mdx):事件设计规范和最佳实践 --- **最后更新时间**:2026 年 1 月 28 日 **许可证**:Apache-2.0