帮助中心 > 技术文档 > 客户端SDK > Web JS SDK > 插件集成

1. 功能介绍

为了扩展Web SDK的功能, 采用了注入插件化的架构方式,方便用户按需使用扩展功能。

2. 内置插件

在SDK中内置了一些插件,这些插件默认均未启动,若使用,可通过配置项方式或use方法的方式进行启动。
注意:配置项方式需要在SDK版本在4.0.0及以上,以下是内置插件列表:

名称 说明
PageLeave 页面浏览时长插件
SiteLinker 多域名打通插件
HinaABTest abTest插件

2.1. 页面浏览时长(PageLeave)

页面浏览时长用于反映用户在某些页面上浏览时间的长短。

属性 类型 默认值 说明
custom_props object 自定义属性
heartbeat_interval_time number 5 心跳记录刷新时间,即每隔几秒保存最新的数据,单位秒
max_duration number 432000 最大浏览时长, 默认432000秒 (5天) ,单位秒
isCollectUrl function 是否采集当前页面浏览时长, 返回 true 表示采集,返回 false 或者不返回则为不采集

支持两种方式开启,代码示例:

// 第一种方式,通过配置项的方式(4.0.0版本开始支持)
hina.init({
  autoTrackConfig:{
    // pageLeaveAutoTrack: true, // 或配置具体的对象形式
    pageLeaveAutoTrack:{
      custom_props:{
        name: 'abc',
      },
      heartbeat_interval_time: 5,
      max_duration: 432000,
      isCollectUrl: function(url) {
        // 自己的业务逻辑
        return true; // 返回true为采集,false为不采集
      }
    }
    // 其他属性...
  },
  // 其他属性...
})

// 第二种方式,通过use插件的方式开启
hina.use('PageLeave',{
  custom_props:{
    name: 'abc',
  },
  heartbeat_interval_time: 5,
  max_duration: 432000,
  isCollectUrl: function(url) {
    // 自己的业务逻辑
    return true; // 返回true为采集,false为不采集
  },
});

2.2. 多域名打通(SiteLinker)

多域名打通是可以将两个不同域名的网站上的用户行为统一,它可以让您更有效地观察相关网站用户的转化历程。

注意:只有 a 标签跳转和父元素是 a 标签跳转这两种情况可以实现跨域打通。

属性 类型 默认值 含义
re_login boolean false true:如果从已登录的页面跳转过来,即使当前网页已经登录,当前网页仍然会以之前网页的登录 id 再次登录。
linker object 具体网站链接配置项,类型为数组,有两个属性:
part_url: string类型,值为打通网站网址的一部分,建议值为打通网站的域名。
after_hash: boolean类型,建议fasle:
false表示将 _hnsdk 参数放在 URL 的 search 部分(即 # 前的 ?部分)
true表示将 _hnsdk 参数放在 URL 的 hash 部分(即 # 后部分)
希望打通的网域 配置 海纳 a 标签 href 地址 来源网域是否登录状态 a 标签打通结果
haishuu.com
{part_url:’example.com’, after_hash: false} https://www.haishuu.com/index https://www.haishuu.com/index?_hnsdk=u+accountID
example.com {part_url:’haishuu.com’, after_hash: false} http://example.com/index http://example.com/index?_hnsdk=a+anonymousId

after_hash示例:

url after_hash 结果
http://example.com false
true
http://example.com?_hnsdk=accountID
http://example.com#?_hnsdk=accountID
http://example.com#index false
true
http://example.com?_hnsdk=accountID#index
http://example.com#index?_hnsdk=accountID
http://example.com?a=123#index false
true
http://example.com?a=123&_hnsdk=accountID#index
http://example.com?a=123#index?_hnsdk=accountID
http://example.com?a=123#index?b=11 false
true
http://example.com?a=123&_hnsdk=accountID#index?b=11
http://example.com?a=123#index?b=11&_hnsdk=accountID

打通结果说明:

A 域名页面 B 域名页面 打通结果说明
匿名 ID 匿名 ID B 域名页面的匿名 ID 会被 A 的匿名 ID 替换
登录 ID 匿名 ID B 域名页面的匿名 ID 会和 A 的登录 ID 执行 login
匿名 ID 登录 ID 1. B 域名页面的匿名 ID 会被 A 的匿名 ID 替换
2. B 域名页面的登录 ID 会和 A 的匿名 ID 执行 trackSignup
登录 ID 登录 ID 1. 如果未配置 re_login ,不做任何处理
2. 如果 re_login 配置值为 true,B 域名页面会以 A 的登录 ID 执行 login

原理说明:

Web JS SDK 默认生成一个唯一的 account ID 并永久保存在浏览器中的 Cookie,用来标识用户。而 Cookie 是跟域名绑定的,所以用户 ID 的标识理论上是限定在了一个域名下。

通过在多域名间共享 account ID,使多域名打通得以实现。account ID 保存在浏览器的 Cookie 中,只有同一网域中的网页才能访问 account ID。如果您拥有多个网域并希望将它们视为同一个资源,则需要设法在您希望分析的所有网域间共享 account ID。

在需要打通的网域上,为 linker 参数的 part_url 属性配置值后,SDK 将检查网址中的 a 标签的链接。如果找到了包含 part_url 的链接后,将提取该域名下的 account ID 拼接到这个连接上,跳转到目标网域后,截取页面网址中的链接器参数,获取并替换当前域名下的 account ID。

例如,想要实现 haishuu.com 和 example.com 的跨域打通,您只需要在两个域名下集成 Web JS SDK,并均配置下面的代码即可实现跨域打通。在配置和运行后,SDK 将自动监听页面 a 标签跳转,并在导航即将开始之前,为这些链接自动添加链接器参数。

当用户到 haishuu.com 域名时,SDK 将自动检查网址中的 a 标签的链接,如果找到了包含 part_url 的链接后,将提取该域名下的 account ID 作为链接器参数拼接到这个连接上,跳转到 example.com 域名时,SDK 将截取 _hnsdk 参数,并将获取到的 account ID 替换 example.com 的 account ID,实现两个域名间的用户统一。同理由 example.com 跳转到 haishuu.com 也是如此实现跨域打通。

可以通过两种方式开启,代码示例:

// 第一种方式:通过配置项的方式开启(4.0.0版本开始支持)
hina.init({
  siteLinkerConfig: {
    linker:[{  part_url:'example.com', after_hash:false  }],
    re_login: false
  },
  // 其他属性...
})

// 第二种方式:通过use插件的方式开启
const siteLinker = hina.use('SiteLinker', {
  linker:[{ part_url: 'example.com', after_hash: false }],
  re_login: true,
});

2.3. ABTest插件

参数 默认值 含义
url 分流试验请求地址

可以通过两种方式开启,代码示例:

// 第一种方式:通过配置项的方式开启(4.0.0版本开始支持)
hina.init({
  abTestingPluginConfig: {
    url: 'xxx'
  },
  // 其他属性...
})

// 第二种方式:通过use插件的方式开启
const abTest = hina.use('HinaABTest', {
  url: 'xxx'
})

获取试验变量:

开启abtest插件后,通过 API 获取具体试验的变量值,根据获取试验变量值的方式,可分为下面三种策略:

  • fetchCacheABTest :读取本地缓存,缓存不存在时使用默认值
  • asyncFetchABTest :忽略本地缓存,从服务端获取数据
  • fastFetchABTest :优先读取本地缓存,缓存不存在时从服务端获取数据

如何确定应该选择哪个API获取试验变量值?

  1. 一般情况下,我们推荐使用fastFetchABTest获取试验变量值。
  2. 如果您对性能有要求,可以使用fetchCacheABTest, 只从本地缓存中获取变量值,但可能导致用户无法及时命中最新的试验。
  1. 请确保对A/B分流返回的 result 结果 & 接口中使用的默认值,都做了正常的业务逻辑处理!
  2. 请确保默认值 defaultValue 和当前试验值类型相同。比如参数对应试验值为 INTEGER 类型,则传入的 defaultValue 也必须是 INTEGER 类型,同时返回的试验结果 result 也是 INTEGER 类型

以 fastFetchABTest 为例,可在相应的业务逻辑中添加如下代码:

// 在入口文件中开启abtest插件功能
const abTest = hina.use('HinaABTest', {
  url: 'xxx'
})
// 可以将abtest实例挂载到window上,以便全局使用
window.abTest=abTest;

// 在对应的业务文件中调用fastFetchABTest方法进行业务处理
// INTEGER 类型试验(第二个参数 0,表示未命中试验时,会返回此默认值,请根据业务需要更改此处的值)
window.abtest.fastFetchABTest({
  abtestExperimentId:'具体的试验ID',
  paramName:"具体的试验参数",
  defaultValue:0, // 默认值
  valueType:"INTEGER",// 值类型
  timeoutMilliseconds: 3000, //获取试验结果的超时时间,超时后返回 defaultValue,默认3000ms
  callback: function(result){
    // TODO 请根据 result 进行自己的试验
  }
});

3. 自定义插件(4.0.0版本开始支持)

为了更大程度的支持用户多元化需求,Web JS SDK在4.0.0开始新增了plugins配置项,支持运行用户自定义的插件。

插件的具体开发规范如下(为了在开发过程中拥有更好的类型提示,建议使用typescript开发):

1:插件需要定义为一个class类

2:类上有4个基础属性:

name:插件名

isReady:是否运行了插件(可以启动避免重复多次运行)

init:初始化插件方法(插件的功能启动均在此方法中运行)

transform:数据上报前,可以在此方法进行数据格式化一些列操作,如果不需要进行数据上报功能,

则该方法不用进行数据返回或返回undefined

下面给出两个自定义插件的demo

1:监听点击事件,并上报数据

(typescript版本)

import hina, {TrackOptions,PluginBase, TrackInstance, ReportDataType} from 'hina-cloud-js-sdk'
/**
 * TrackOptions:埋点SDK所有配置项信息
 * PluginBase:插件抽象类,插件继承它时可以提供详细的类型提示
 * TrackInstance:hina的实例对象,提供SDK所有的方法
 * ReportDataType:上报数据的typescript类型声明
 */
interface IData{
  a:string
  b:string
}
class CustomClick extends PluginBase<TrackOptions, TrackInstance>{
  name="CustomClick"
  isReady=false
  constructor(public options:TrackOptions,public context:TrackInstance) {
    super(options,context);
  }
  init(notify: (data: IData) => void) {
    if (this.isReady){
      return
    }
    this.isReady=true
    window.addEventListener('click',e=>{
      // 调用notify方法会触发transform方法的执行
      notify({
        a:'a',
        b:'b'
      })
    })
  }
  transform(data: IData): ReportDataType<IData> {
    // 在这里我想上报 H_WebClick 事件
    const props = this.context.getReportData('track', 'H_WebClick', data)
    return props
  }
}

// 使用方式:
hina.init({
  // 其他配置项省略
  plugins:[
    CustomClick
  ]
})

(javascript版本)

import hina from 'hina-cloud-js-sdk'
class CustomClick {
  name = "CustomClick"
  isReady = false
  constructor(options, context) {
    this.options = options
    this.context = context
  }
  init(notify) {
    if (this.isReady) {
      return
    }
    this.isReady = true
    window.addEventListener('click', e => {
      // 调用notify方法会触发transform方法的执行
      notify({
        a:'a',
        b:'b'
       })
      })
    }
    transform(data) {
      // 在这里我想上报 H_WebClick 事件
      const props = this.context.getReportData('track', 'H_WebClick', data)
      return props
    }
}

// 使用方式:
hina.init({
  // 其他配置项省略
  plugins:[
    CustomClick
  ]
})

2:监听点击事件,不进行上报,监听到点击事件后做一些自己的业务处理

(typescript版本)

import hina, {TrackOptions,PluginBase, TrackInstance, ReportDataType} from 'hina-cloud-js-sdk'
/**
 * TrackOptions:埋点SDK所有配置项信息
 * PluginBase:插件抽象类,插件继承它时可以提供详细的类型提示
 * TrackInstance:hina的实例对象,提供SDK所有的方法
 * ReportDataType:上报数据的typescript类型声明
 */
class CustomClick extends PluginBase<TrackOptions, TrackInstance>{
  name="CustomClick"
  isReady=false
  constructor(public options:TrackOptions,public context:TrackInstance) {
    super(options,context);
  }
  init() {
    if (this.isReady) {
      return
    }
    this.isReady=true
    window.addEventListener('click',e=>{
      // todo 触发点击事件后,处理自身业务逻辑
    })
 }
  transform(): ReportDataType<any> {
    // 不进行数据上报
    return undefined
  }
}
// 使用方式:
hina.init({
  // 其他配置项省略
  plugins:[
    CustomClick
  ]
})

(javascript版本)

import hina from 'hina-cloud-js-sdk'
class CustomClick {
  name = "CustomClick"
  isReady = false
  constructor(options, context) {
    this.options = options
    this.context = context
  }
  init() {
    if (this.isReady) {
      return
    }
    this.isReady = true
    window.addEventListener('click', e => {
      // todo 触发点击事件后,处理自身业务逻辑
    })
  }
  transform() {
    // 不进行数据上报
    return undefined
  }
}

// 使用方式:
hina.init({
  // 其他配置项省略
  plugins:[
    CustomClick
  ]
})
作者:石文华  创建时间:2023-05-29 19:28
最后编辑:张永健  更新时间:2025-04-01 16:17