You need to enable JavaScript to run this app.
导航
Web/JS SDK FAQ
最近更新时间:2024.07.09 17:22:55首次发布时间:2024.04.30 15:17:24

Web SDK上报逻辑与存储策略

Web SDK数据上报策略

默认“接近实时”上报事件,SDK使用了一个队列,等待30ms,在等待时间内触发的事件会合并为一次请求进行上报,如果未达到30ms的等到时间,事件数量达到了10条话就立即进行合并为一次请求进行上报。可以通过设置max_report参数来更改条数(10是默认条数)。

web_id请求逻辑

web_id在sdk初始化即调用init方法时,会向服务器发起webid的请求(https://xxxx/webid
图片
请求参数为:app_id,当前URL,URL的referer,当前浏览器的useragent,以及user_unique_id(一般为空值),主要依赖的是appid和当前所处环境,请求会在服务端生成一个唯一的webid返回,如下图:
图片
拿到web_id后会缓存在本地,只要appid和域名不变,不手动清除缓存,都不再请求服务器获取web_id。

Web SDK的用户id存储逻辑

WebSDK初始化完成后,默认情况下,会将webid/user_unique_id存储在浏览器的localStorage中(当前页面的域名下),只要用户不手动清除浏览器的缓存,那么这个存储将会永久存在,且值不会改变。
在一些特殊的场景下,比如需要统计跨子域名(a.b.com和c.b.com)页面的信息时,可以打开SDK的cookie存储开关(具体查看SDK的功能配置)。此时,SDK会将webid/user_unique_id存储在浏览器的cookie中(默认过期时间为7天,可通过配置更改),在cookie未过期之前,这个存储值不会改变。在cookie过期后,或者用户手动清除了浏览器的cookie,那么SDK将会重新生成webid。

Web SDK session id生成和存储逻辑

  1. 用户首次访问页面时,SDK初始化生成sessionid,存储sessionid于sessionstorage中,同时记录生成的时间戳。
  2. 每当这个页面有事件触发(用户主动触发+SDK自动上报触发)后,则去更新sessionstorage中sessionid的时间戳。
  3. 当在同一个页面里,30分钟内没有任何操作(用户没有触发事件上报,SDK也没有自动上报任何事件),则认为sessionid过期,此时生成一个新的sessionid,并更新sessionid的时间戳。
  4. 当页面中有按钮点击打开一个新窗口,根据sessionstorage此时属于新会话,则会生成新的sessionid。
  5. 当页面关闭时,清空sessionstorage,下次再打开页面,生成新的sessionid。
  6. 在sessionid有效期内,每次事件上报都带上sessionid,作为公共参数。

bav2b_beat 页面心跳事件采集逻辑

页面心跳事件,分别在页面访问,滚动页面后停止500ms,离开页面时上报各上报一次,详情参考文档2.4.4章节https://www.volcengine.com/docs/6285/112163

Web SDK能力与使用咨询

Web多页面应用集成SDK,公共属性是否每个页面都要上报?

初始化和公共属性每个页面都需要代码写一次,user_unique_id会缓存,设置一次即可。

Web微前端项目,主应用和子应用分别接入不同应用(app_id不同),这种场景下有什么解决方案吗?

可以通过多实例方式解决,详情参考此文档:3. Web/JS 多实例使用

有多个Web页面域名时,如何跨域名打通WebID保持WebID不变?

  • 跨子域名打通WebID时,例如 a.yourdomain.comb.yourdomain.com的情况:
    您可在集成并初始化SDK时,通过配置cross_subdomain参数的方式来实现,设置为true时多个子域名下使用同一浏览器访问的匿名用户会被自动识别为同一个用户。详情请参见3.5 初始化配置一览表
  • 跨web站点打通WebID时,例如yourdomain.com.cnyourdomain.com.hk的情况:
    • 您可以集成并初始化SDK时,打开并配置自定义webid,通过手动设置webid来统一多个站点web页面的webid。详情请参见3.4 自定义webid
    • 您也可以集成并初始化SDK时,打开并设置匿名ID,通过匿名ID来代替webid,实现统一多个站点web页面的webid的效果。详情请参见1.3 匿名ID

集成Web/JS SDK如何查看用户的ssid?

//获取平台生成的各种ID
window.collectEvent('getToken', (res) => {
    console.log(res)
}); 
 
 window.collectEvent('getToken', (token) => {
    // token数据内容类似如下:
    // {
    //    "web_id":"6748002161499735560",
    //    "ssid":"579bc89a-bd45-4021-8314-669c35f38e3d",
    //    "user_unique_id":"xxx",
    // }
    window.collectEvent('test', {
      id: `web_id/ssid的值`
    });
});

Web SDK是否有采集页面崩溃的能力

没有,Web SDK只是埋点采集数据,不采集页面错误,如需要采集页面崩溃可以引导客户购买apm产品。

Web SDK圈选事件的圈选范围是什么?

圈选规则限制,当一个元素的子元素超过2层时会过滤,如果要圈选到外层元素,建议不要有超过2层子元素。

Web/JS SDK接入,如果不主动上报数据,默认会采集哪些数据?

只要集成SDK,并初始化完成就会采集预置事件和属性,详细参考文档:Web预置事件及属性
如果需要采集全埋点数据,可以通过打开全埋点开关,全埋点事件说明:全埋点预置事件和属性

Web SDK 的reportTime和max_report参数的意义是什么?

埋点上报策略分为2种,默认max_report是10,第一种,30ms内触发的埋点数量大于10了,就直接上报;第二种,30ms内没有触发这么多,就会等待30ms后再把之前的埋点一起上报。

页面停留时长「total_duration」或「duration」有什么区别?

duration是活跃时长,简单的说就是用户在实际使用的时长;
total_duration是页面打开到关闭的总时长,包含用户切换了页面没有在实际使用的时长。比如最小化、后台等,切换页面会被理解为“离开页面”这时候会上报一次close事件。

predefine_pageview和bav2b_page的区别?

  • predefine_pageview是Web和小程序的预置页面访问事件,移动端没有;
  • bav2b_page是全埋点页面访问事件,只要打开开关就会采集;
  • 对于Web平台,两个也有区别,bav2b_page是全埋点上报的事件,spa参数为false的情况,bav2b_page单页应用的路由切换时中也会上报,predefine_pageview只会上报页面打开的时候上报一次。spa为 true,bav2b_page和predefine_pageview是一样的,在JS SDK 5.0版本以后,bav2b_page和predefine_pageview上报是统一的。

collectEvent有ts类型定义吗?

interface IInitParam {
  app_id: number;
  channel?: 'cn' | 'va' | 'sg';
  channel_domain?: string;
  app_key?: string;
  caller?: string;
  log?: boolean;
  disable_webid?: boolean;
  disable_sdk_monitor?: boolean;
  disable_storage?: boolean;
  autotrack?: any;
  enable_stay_duration?: any;
  disable_route_report?: boolean;
  disable_session?: boolean;
  disable_heartbeat?: boolean;
  disable_auto_pv?: boolean;
  enable_spa?: boolean;
  user_unique_type?: string;
  enable_ab_test?: boolean;
  max_storage_num?: number;
  enable_storage?: boolean;
  enable_cookie?: boolean;
  enable_ab_visual?: boolean;
  cross_subdomain?: boolean;
  cookie_domain?: string;
  enable_multilink?: boolean;
  multilink_timeout_ms?: number;
  reportTime?: number;
  timeout?: number;
  max_report?: number;
  report_url?: string;
  maxDuration?: number;
  ab_channel_domain?: string;
  configPersist?: number;
  extend?: any;
  ab_timeout?: number;
  disable_tracer?: boolean;
  extendConfig?: any;
  filter?: any;
  spa?: boolean;
  cookie_expire?: number;
  enable_custom_webid?: boolean;
  disable_track_event?: boolean;
  allow_hash?: boolean;
  enable_native?: boolean;
  ab_cross?: boolean;
  ab_cookie_domain?: string;
  disable_ab_reset?: boolean;
  enable_encryption?: boolean;
  enable_anonymousid?: boolean
  enable_debug?: boolean
  crypto_publicKey?: string
  encryption_type?: string
  encryption_header?: string
  enable_logsetting?: boolean
  enable_track_id?: boolean
  track_level?: number
  overlay_opacity?: number
  auto_exposure_expriment?: boolean
}


interface IConfigParam {
  _staging_flag?: 0 | 1;
  user_unique_id?: string;
  disable_auto_pv?: boolean;
  web_id?: string;
  user_type?: number;
  os_name?: string;
  os_version?: string;
  device_model?: string;
  ab_client?: string;
  ab_version?: string;
  ab_sdk_version?: string;
  traffic_type?: string;
  utm_source?: string;
  utm_medium?: string;
  utm_campaign?: string;
  utm_term?: string;
  utm_content?: string;
  platform?: string;
  browser?: string;
  browser_version?: string;
  region?: string;
  province?: string;
  city?: string;
  language?: string;
  timezone?: number;
  tz_offset?: number;
  screen_height?: number;
  screen_width?: number;
  referrer?: string;
  referrer_host?: string;
  os_api?: number;
  creative_id?: number;
  ad_id?: number;
  campaign_id?: number;
  ip_addr_id?: number;
  user_agent?: string;
  verify_type?: string;
  sdk_version?: string;
  channel?: string;
  app_id?: number;
  app_name?: string;
  app_version?: string;
  app_install_id?: number;
  user_id?: any;
  device_id?: any;
  wechat_openid?: string,
  wechat_unionid?: string,
  evtParams?: EventParams,
  reportErrorCallback?(eventData: any, errorCode: any): void;
  [key: string]: any;
}


type EventParams = Record<string, any>;


export type SdkOption = Omit<IInitParam, 'app_id'>;


export type SdkHookListener = (hookInfo?: any) => void;


export interface Plugin {
  apply(sdk: Sdk, options: SdkOption): void;
}
export interface PluginConstructor {
  new(): Plugin;
  pluginName?: string;
  init?(Sdk: SdkConstructor): void;
}


declare enum SdkHook {
  Init = 'init',
  Config = 'config',
  Start = 'start',
  Ready = 'ready',
  TokenComplete = 'token-complete',
  TokenStorage = 'token-storage',
  TokenFetch = 'token-fetch',
  TokenError = 'token-error',
  ConfigUuid = 'config-uuid',
  ConfigWebId = 'config-webid',
  ConfigDomain = 'config-domain',
  CustomWebId = 'custom-webid',
  TokenChange = 'token-change',
  TokenReset = 'token-reset',
  ConfigTransform = 'config-transform',
  EnvTransform = 'env-transform',
  SessionReset = 'session-reset',
  SessionResetTime = 'session-reset-time',
  Event = 'event',
  Events = 'events',
  EventNow = 'event-now',
  CleanEvents = 'clean-events',
  BeconEvent = 'becon-event',
  SubmitBefore = 'submit-before',
  SubmitScuess = 'submit-scuess',
  SubmitAfter = 'submit-after',
  SubmitError = 'submit-error',
  SubmitVerify = 'submit-verify',
  SubmitVerifyH = 'submit-verify-h5',
  Stay = 'stay',
  ResetStay = 'reset-stay',
  StayReady = 'stay-ready',
  SetStay = 'set-stay',
  RouteChange = 'route-change',
  RouteReady = 'route-ready',
  Ab = 'ab',
  AbVar = 'ab-var',
  AbAllVars = 'ab-all-vars',
  AbConfig = 'ab-config',
  AbExternalVersion = 'ab-external-version',
  AbVersionChangeOn = 'ab-version-change-on',
  AbVersionChangeOff = 'ab-version-change-off',
  AbOpenLayer = 'ab-open-layer',
  AbCloseLayer = 'ab-close-layer',
  AbReady = 'ab-ready',
  AbComplete = 'ab-complete',
  Profile = 'profile',
  ProfileSet = 'profile-set',
  ProfileSetOnce = 'profile-set-once',
  ProfileUnset = 'profile-unset',
  ProfileIncrement = 'profile-increment',
  ProfileAppend = 'profile-append',
  ProfileClear = 'profile-clear',
  TrackDuration = 'track-duration',
  TrackDurationStart = 'track-duration-start',
  TrackDurationEnd = 'track-duration-end',
  TrackDurationPause = 'track-duration-pause',
  TrackDurationResume = 'tracl-duration-resume',
  Autotrack = 'autotrack',
  AutotrackReady = 'autotrack-ready',
}
interface SdkConstructor {
  new(name: string): Sdk;
  instances: Array<Sdk>;
  usePlugin: (plugin: PluginConstructor, pluginName?: string) => void;
}
interface Sdk {
  Types: typeof SdkHook;
  on(type: string, hook: SdkHookListener): void;
  once(type: string, hook: SdkHookListener): void;
  off(type: string, hook?: SdkHookListener): void;
  emit(type: string, info?: any, wait?: string): void;
  init(options: IInitParam): void;
  config(configs?: IConfigParam): void;
  getConfig(key?: string): Record<string, any>;
  setDomain(domain: string): void;
  start(): void;
  send(): void;
  set(type: string): void;
  event(event: string, params?: EventParams): void;
  beconEvent(event: string, params?: EventParams): void;
  event(
    events:
      | Array<[string, EventParams] | [string, EventParams, number]>
  ): void;
  predefinePageView(params: any): void;
  clearEventCache(): void;
  setWebIDviaUnionID(unionId: string): void;
  setWebIDviaOpenID(openId): void;
  getToken(callback: (info: Record<string, string | number>) => void, timeout?: number): void;
  resetStayDuration(url_path?: string, title?: string, url?: string): void;
  resetStayParams(url_path?: string, title?: string, url?: string): void;
  profileSet(profile: any): void;
  profileSetOnce(profile: any): void;
  profileIncrement(profile: any): void;
  profileUnset(key: string): void;
  profileAppend(profile: any): void;
  startTrackEvent(eventName: string): void;
  endTrackEvent(eventName: string, params: any): void;
  pauseTrackEvent(eventName: string): void;
  resumeTrackEvent(eventName: string): void;
  setExternalAbVersion(vids: string): void;
  getVar(name: string, defaultValue: any, callback: (value: any) => void): void;
  getAllVars(callback: (value: any) => void): void;
  getAbSdkVersion(): string;
  onAbSdkVersionChange(callback: (vids: string) => void): () => void;
  offAbSdkVersionChange(callback: (vids: string) => void): void;
  setExternalAbVersion(vids: string | null): void;
  getABconfig(params: Record<string, any>, callback: (value: any) => void): void;
  openOverlayer(): void;
  closeOverlayer(): void;
  autoInitializationRangers(
    config: IInitParam & { onTokenReady: (webId: string) => void },
  ): void;
}

type FunctionKeysObject<T extends Record<string, any>> = {
  [K in keyof T]: T[K] extends Function ? T[K] : never
}
type InnerEventsMap = FunctionKeysObject<Sdk>
type CustomEventsMap = Record<string, (params?: Record<string, any>) => void>
type EventsMap = InnerEventsMap & CustomEventsMap
type CollectEvent = <T extends keyof EventsMap>(key: T, ...args: Parameters<EventsMap[T]>) => void

interface Window {
  collectEvent: CollectEvent
}

Web SDK支持哪些浏览器?

只要是标准的浏览器环境,能支持原生 JavaScript(不需要 ES6 ) 就可以使用,与操作系统、平台类型、浏览器类型、浏览器版本无关。 不保证一些小众浏览器没有实现标准的 JavaScript ,导致一些属性有差异,与操作系统、平台类型、浏览器类型、浏览器版本有关。
部分功能需要相对较新的浏览器才能支持,例如批量发送需要 LocalStorage 存储,如果一些功能(例如批量发送)在版本浏览器不支持的话,SDK 不会报错,而是自动降级(使用图片发送),或者去除这个功能。

浏览器

支持说明

IE6~9

IE7、IE8受限支持(仅支持事件上报,不支持view曝光),其他版本IE浏览器不支持

IE10~11

Chrome

Safari

Edge

FireFox

Opera

web sdk是否兼容旧版IE浏览器?

带有core路径的js文件(含base或者其他),兼容了低版本IE浏览器(IE11以下)。

  • IE9及以上:
    • SaaS使用:https://lf3-data.volccdn.com/obj/data-static/log-sdk/collect/5.0/core/collect-rangers-v5.1.x.js
    • 私有化使用:https://lf3-data.volccdn.com/obj/data-static/log-sdk/collect/5.0/core/collect-privity-v5.1.x.js
  • IE7、IE8:https://lf3-data.volccdn.com/obj/data-static/log-sdk/collect/5.0/core/collect-base-rangers-v5.1.x.js

    注意

    IE7、IE8仅支持事件上报,不支持view曝光。

web sdk是否兼容低版本Google浏览器?

谷歌6.x版本之前可以通过使用带core的js文件:https://lf3-data.volccdn.com/obj/data-static/log-sdk/collect/5.0/core/collect-privity-v5.1.6.js

故障/报错的排查处理

元素曝光事件(元素的曝光事件非实验曝光)在IE浏览器无法上报

元素曝光事件不支持IE浏览器,只支持到EDGE(除了IE的其他主流浏览器都支持)。

集成了Web SDK 配置多链接实验时,提示未安装SDK,如何处理?

多链接实验需要在初始化的时候开启如下配置: enable_ab_visual: true。

前向地址referrer为空如何排查?

(1)SDK版本是否是5.0以上;
(2)是否是SPA应用,init有没有设置spa=true;
(3)服务端请求的响应头里面对于refer的权限是否设置了禁用referrer