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.sendBeacon → fetch(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-catch 或 Promise.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 中提供 accessKey 和 secretKey
"keyEndpoint is required for session key exchange mode"会话密钥模式缺少 keyEndpoint在 SdkConfig 中提供 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() 可获取性能指标快照,包含 requestStartAt、requestEndAt、renderStartAt、renderEndAt、errors 等字段。

技术支持 ​

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