Skip to content

H5 集成说明

概述

优聚智汇 H5 广告 SDK 采用统一入口设计:

  • 单例入口UjuAdSdk 单例,通过 init() 初始化、createAd() 创建广告
  • 统一创建:所有广告类型通过同一个 createAd(container, options) 方法创建,广告类型由服务端返回的 adType 字段决定,客户端无需指定
  • 自动渲染:SDK 内部完成广告素材的 DOM 渲染,无需手动拼接 HTML
  • 自动上报:曝光、点击、视频进度等事件由 SDK 内部自动监听并上报,不提供外部事件订阅 API(无 on()/off()/emit() 方法)

本文档基于 H5 SDK 源码(h5/src/)编写,所有 API 均为真实存在的方法签名。

SDK 初始化

1. 构造配置对象

javascript
// 构造 SDK 配置(appId 和 adEndpoint 必填)
const config = {
  appId: "YOUR_APP_ID",           // 必填:应用 ID
  adEndpoint: "https://adx.ujuad.com/bid",  // 必填:广告请求地址
  accessKey: "YOUR_ACCESS_KEY",   // ADX 协议必填:访问密钥
  secretKey: "YOUR_SECRET_KEY",   // ADX 协议必填:加密密钥
  keyEndpoint: "https://adx.ujuad.com/key", // 可选:会话密钥交换地址
  reportEndpoint: "https://adx.ujuad.com/report", // 可选:事件上报地址
  debug: true,                    // 可选:调试模式,生产环境请设为 false
};

2. 调用 init 初始化

javascript
// 初始化 SDK(幂等,重复调用会直接返回)
UjuAdSdk.init(config);

// 初始化后即可创建广告实例

注意init() 是同步方法,无返回值。若未调用 init() 直接调用 createAd(),会抛出 Error("UjuAdSdk.init must be called first")

SdkConfig 字段参考

字段类型必填默认值说明
appIdstring✅ 是应用 ID
adEndpointstring✅ 是广告请求服务地址
keyEndpointstring❌ 否会话密钥交换地址(会话密钥模式必填)
accessKeystring❌ 否ADX 协议访问密钥(ADX 协议必填)
secretKeystring❌ 否ADX 协议加密密钥(ADX 协议必填)
protocolVersionstring❌ 否"3.3.0"ADX 协议版本
reportEndpointstring❌ 否事件上报地址
maxConcurrencynumber❌ 否3最大并发请求数
requestTimeoutMsnumber❌ 否200单次请求超时(毫秒)
retryCountnumber❌ 否2失败重试次数(退避 200×2^attempt ms)
debugboolean❌ 否false是否开启调试日志
allowHttpsOnlyFallbackboolean❌ 否false仅 HTTPS 回退开关
hmacSecretstring❌ 否HMAC 签名密钥

创建广告

基本用法

通过 UjuAdSdk.createAd(container, options) 创建广告实例:

javascript
// 方式一:container 为选择器字符串
const ad = UjuAdSdk.createAd("#ad-container", {
  slotId: "YOUR_SLOT_ID",   // 必填:广告位 ID
  autoLoad: true,            // 可选:创建后自动加载
});

// 方式二:container 为 DOM 元素
const containerEl = document.getElementById("ad-container");
const ad = UjuAdSdk.createAd(containerEl, {
  slotId: "YOUR_SLOT_ID",
});

说明:若 container 为字符串但找不到对应元素,会抛出 Error("ad container not found")

AdCreateOptions 字段参考

字段类型必填默认值说明
slotIdstring✅ 是广告位 ID
autoLoadboolean❌ 否undefined是否创建后自动调用 load()
prioritynumber❌ 否0请求优先级,数值越大越优先
userIdstring❌ 否用户 ID(会被 hash 后作为 userIdHash)

AdInstance 方法

createAd() 返回一个 AdInstance 对象,提供以下方法:

方法签名说明
load()() => Promise<void>加载广告;成功后状态变为 rendered,DOM 自动渲染
refresh()() => Promise<void>刷新广告(等同于再次 load());已销毁时静默返回
destroy()() => void销毁广告实例;解绑事件、清空容器、状态变为 destroyed(幂等)
getState()() => AdState获取当前状态:"idle" / "loading" / "rendered" / "destroyed"
getMetrics()() => AdMetrics获取性能指标快照(浅拷贝)
registerMacro(name, resolver)(string, (ad: AdPayload) => string) => void注册自定义宏

加载与刷新

javascript
const ad = UjuAdSdk.createAd("#ad-container", {
  slotId: "YOUR_SLOT_ID",
});

// 手动加载广告
ad.load()
  .then(() => {
    console.log("广告加载并渲染成功");
    console.log("当前状态:", ad.getState()); // "rendered"
  })
  .catch((err) => {
    console.error("广告加载失败:", err.message);
    console.log("当前状态:", ad.getState()); // "idle"
  });

// 刷新广告(重新请求并渲染)
ad.refresh().catch((err) => {
  console.error("刷新失败:", err.message);
});

状态查询

javascript
// 获取广告状态
const state = ad.getState();
// 可能的值:"idle" | "loading" | "rendered" | "destroyed"

// 获取性能指标
const metrics = ad.getMetrics();
console.log(metrics);
// {
//   requestStartAt: 1700000000000,  // 请求开始时间戳
//   requestEndAt: 1700000000200,    // 请求结束时间戳
//   renderStartAt: 1700000000201,   // 渲染开始时间戳
//   renderEndAt: 1700000000250,     // 渲染结束时间戳
//   errors: 0                        // 错误计数
// }

销毁广告

javascript
// 销毁广告实例(幂等,可安全多次调用)
ad.destroy();

// 销毁后状态变为 "destroyed",容器内容被清空
console.log(ad.getState()); // "destroyed"

// 销毁后调用 load() 会抛出 Error("cannot load destroyed ad")
// 销毁后调用 refresh() 会静默返回(不抛错)

销毁所有广告

javascript
// 一次性销毁所有已创建的广告实例
UjuAdSdk.destroyAll();

广告类型

H5 SDK 采用服务端决定广告类型的设计:广告类型由服务端返回的 AdPayload.adType 字段决定,客户端无需也无法指定广告类型。

adType 值广告类型渲染说明
1信息流 / Native默认类型,支持 wide / narrow / mini 三种子布局
2激励视频含"激励视频"标识徽章
3横幅 Banner横幅尺寸
4插屏 Interstitial全屏覆盖,底部 overlay
5开屏 Splash全屏,含"跳过"按钮
javascript
// 所有广告类型的创建方式完全相同
const ad = UjuAdSdk.createAd("#ad-container", {
  slotId: "YOUR_SLOT_ID",
  autoLoad: true,
});

// 服务端会根据 slotId 配置返回对应类型的广告
// SDK 自动根据返回的 adType 选择对应的渲染模板

事件上报机制

重要说明:无外部事件订阅 API

H5 SDK 不提供 on() / off() / emit() 等事件订阅方法。所有广告事件(曝光、点击、视频进度)均由 SDK 内部自动监听并上报,开发者无需也无法手动触发或订阅。

自动上报的事件

事件类型触发条件上报方式
impression(曝光)广告容器可见面积 ≥ 50% 且持续 1000msIntersectionObserver 监测
click(点击)用户点击广告容器capture 阶段捕获,先上报再执行跳转
video_progress(视频进度)视频播放至 0% / 25% / 50% / 75% / 100%<video> 的 timeupdate 事件
error(错误)广告加载或渲染失败AdInstance 内部自动上报

上报通道优先级

  1. 优先使用广告返回的 trackers.impression / trackers.click 地址
  2. 其次使用 SdkConfig.reportEndpoint 配置的全局上报地址
  3. 上报方式优先级:navigator.sendBeaconfetch(keepalive: true) → IndexedDB 队列(可重发)
javascript
// 开发者无需编写任何事件上报代码
// SDK 在 ad.load() 成功并渲染后,自动绑定事件监听器
// 广告销毁时(ad.destroy())自动解绑所有监听器

自定义宏

SDK 内置宏引擎,支持在广告素材 URL 中使用宏占位符,在渲染时自动替换。

内置宏

宏名说明
__TIMESTAMP__当前时间戳
__DEVICE_ID__设备 ID
__OS__操作系统
__SLOT_ID__广告位 ID
__REQUEST_ID__请求 ID
__CREATIVE_ID__创意 ID
__RANDOM__随机数
__AUCTION_PRICE__竞价价格

注册自定义宏

javascript
const ad = UjuAdSdk.createAd("#ad-container", {
  slotId: "YOUR_SLOT_ID",
});

// 注册自定义宏(宏名必须匹配 /^__[A-Z_]+__$/ 格式)
ad.registerMacro("__USER_ID__", (adPayload) => {
  return "user_12345";
});

// 注册后,广告素材中出现的 __USER_ID__ 会被自动替换为 "user_12345"

注意:宏名必须匹配正则 /^__[A-Z_]+__$/,否则抛出 Error("invalid macro name: ${name}")

错误处理

H5 SDK 不使用错误码枚举,所有错误均通过 throw new Error(message) 抛出标准 Error 对象。使用 try-catchPromise.catch() 捕获。

常见错误消息

错误消息触发场景解决方案
"UjuAdSdk.init must be called first"未调用 init() 就调用 createAd()确保先调用 UjuAdSdk.init(config)
"UjuAdSdk is not initialized"配置未初始化就访问检查 init() 是否被正确调用
"ad container not found"createAd() 的 container 选择器找不到元素检查 DOM 元素是否存在、选择器是否正确
"cannot load destroyed ad"对已 destroy() 的实例调用 load()销毁后不要再调用 load(),如需重新加载请创建新实例
"ADX protocol requires accessKey and secretKey"ADX 协议模式下缺少密钥SdkConfig 中提供 accessKeysecretKey
"keyEndpoint is required for session key exchange mode"会话密钥模式缺少 keyEndpointSdkConfig 中提供 keyEndpoint
"invalid macro name: ${name}"registerMacro 的宏名格式不对宏名须匹配 /^__[A-Z_]+__$/

错误处理示例

javascript
const ad = UjuAdSdk.createAd("#ad-container", {
  slotId: "YOUR_SLOT_ID",
});

// 使用 Promise.catch 捕获加载错误
ad.load().catch((err) => {
  console.error("广告加载失败:", err.message);
  // SDK 内部会自动通过 reportEndpoint 上报错误事件
});

// 或使用 try-catch(需 async 函数)
async function loadAd() {
  try {
    await ad.load();
    console.log("加载成功");
  } catch (err) {
    console.error("加载失败:", err.message);
  }
}

完整集成示例

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>优聚智汇 H5 SDK 集成示例</title>
  <!-- 引入 UMD 格式 SDK -->
  <script src="ad-sdk.umd.js"></script>
  <style>
    #ad-container {
      width: 100%;
      max-width: 640px;
      margin: 20px auto;
      min-height: 100px;
    }
  </style>
</head>
<body>
  <h1>H5 广告集成示例</h1>

  <!-- 广告容器 -->
  <div id="ad-container"></div>

  <button id="refresh-btn">刷新广告</button>
  <button id="destroy-btn">销毁广告</button>

  <script>
    // 1. 初始化 SDK
    UjuAdSdk.init({
      appId: "YOUR_APP_ID",
      adEndpoint: "https://adx.ujuad.com/bid",
      accessKey: "YOUR_ACCESS_KEY",
      secretKey: "YOUR_SECRET_KEY",
      reportEndpoint: "https://adx.ujuad.com/report",
      debug: true, // 生产环境请设为 false
    });

    // 2. 创建广告实例
    const ad = UjuAdSdk.createAd("#ad-container", {
      slotId: "YOUR_SLOT_ID",
      autoLoad: true, // 自动加载
    });

    // 3. 监听加载结果(通过 Promise,非事件订阅)
    ad.load().catch((err) => {
      console.error("广告加载失败:", err.message);
    });

    // 4. 刷新按钮
    document.getElementById("refresh-btn").addEventListener("click", () => {
      ad.refresh().catch((err) => {
        console.error("刷新失败:", err.message);
      });
    });

    // 5. 销毁按钮
    document.getElementById("destroy-btn").addEventListener("click", () => {
      ad.destroy();
      console.log("广告已销毁,状态:", ad.getState());
    });
  </script>
</body>
</html>

常见问题

Q: 为什么没有 on('load') / on('click') 等事件监听方法?

A: H5 SDK 采用自动上报设计,不提供外部事件订阅 API。曝光、点击、视频进度等事件由 SDK 内部通过 IntersectionObserver 和事件捕获自动监听并上报到服务端。开发者只需调用 load() 并处理 Promise 的 resolve/reject 即可。

Q: 如何指定广告类型(Banner / 激励视频 / 插屏等)?

A: 广告类型由服务端根据 slotId 配置返回,客户端无法指定。不同的 slotId 对应不同的广告类型,请在优聚智汇后台配置广告位时选择对应的广告类型。

Q: 广告加载失败后如何重试?

A: load() 失败后状态会回到 idle,可以直接再次调用 load()refresh() 重试。SDK 内部也有 retryCount(默认 2 次)的自动重试机制。

Q: 页面切换或广告容器被移除后会怎样?

A: SDK 通过 MutationObserver 监听容器从 DOM 移除的事件,会自动触发销毁逻辑(等同于调用 destroy()),无需手动处理。

Q: 如何获取广告的性能数据?

A: 调用 ad.getMetrics() 可获取性能指标快照,包含 requestStartAtrequestEndAtrenderStartAtrenderEndAterrors 等字段。

技术支持

如在集成过程中遇到问题,请联系: