You need to enable JavaScript to run this app.
导航
H5列表页
最近更新时间:2024.12.02 17:26:00首次发布时间:2023.11.10 15:58:15
概述

火山引擎内容定制H5应用是以移动H5页面为载体,具有个性化推荐能力的应用。客户侧研发仅需要将获取到的H5地址拼接业务参数后,嵌入到自身产品业务入口中即可,帮助您实现接入的高效率、低成本

功能说明
对比项H5接入API接入
适用场景产研资源有限,需要快速接入定制产品,完成基础功能的搭建产研资源充足,需要在c端呈现完整的产品功能,用户体验要求高

用户体验

交互样式相对单一
视频播放性能差(加载慢)
不支持视频在列表页播放

交互样式可自定义
视频加载速度、播放性能更好
支持视频在列表页播放

接入成本低(H5链接的拼接和鉴权,预计开发时间为1周)高(ui设计,前端样式开发,服务端接口对接,预计开发时间为1-2月)
前端样式多tab信息流、双feed信息流、伪沉浸式多tab信息流、单列表信息流、双feed信息流、宫格、卡片(单卡片、1.4卡片、2.4卡片)、沉浸式
内容体裁图文、横版短视频、小视频图文、横版短视频、竖版小视频
频道类型自定义频道、标准频道(含本地频道)自定义频道、标准频道(含本地频道)、关注频道
频道推荐方式个性化推荐、时间倒序、热度推荐个性化推荐、时间倒序、热度推荐
运营规则置顶、屏蔽置顶、屏蔽
互动功能分享、展示评论分享、展示评论、点赞、收藏(列表页、详情页都可支持)
基础功能相关推荐、阅读量相关推荐、阅读量、页面UI自定义
作者主页支持支持
关注不支持支持
商品推广不支持支持
推送(push)不支持支持
专题不支持支持
产品体验
频道类型DEMO演示图文频道横版短视频频道竖版小视频频道图文和视频混排频道短视频和小视频混排频道

列表页样式


无图、大图、右图、三图混出


双列feed流


伪沉浸式


无图、大图、右图、三图混出


双列feed流

列表页显示元素

--

  • 标题、封面图、作者名称、发布时间

  • 置顶内容使用无图样式,显示置顶标识

  • 标题、封面图、作者名称、发布时间、视频时长

  • 置顶内容显示置顶标识

  • 作者名称、作者头像、点赞量、评论量、分享量、标题、音乐名称、音乐转盘
  • 标题、封面图、作者名称、发布时间、视频时长

  • 置顶内容使用无图样式,显示置顶标识

  • 标题、封面图、作者名称、发布时间、视频时长
接入步骤
步骤描述

准备工作

  1. 请完成火山引擎账号注册

  2. 如果您首次登录火山引擎控制台,请先完成实名认证

  3. 访问火山引擎内容定制控制台,请先提交试用申请,并等待审核通过。

创建H5链接

  1. 创建应用:登录火山引擎内容定制控制台,点击左侧“应用管理”-“新建应用

  2. 创建频道:应用创建完成后,点击左侧“内容分发”-“新建频道

alt

  1. 创建H5链接:频道创建完成后,点击当前界面右上角的“H5快速接入”。新建H5链接时,可按需对频道进行组合(频道选择顺序,即为H5展示顺序)

    alt

应用接入

  1. 获取链接:H5链接创建完成后,选择需要的频道组合链接,点击“复制链接”即可

    alt

  2. 完成接入:客户侧客户端研发通过webview/iframe等方式,按业务特性拼接相关参数到H5链接中,并嵌入到自有的业务入口中。具体业务参数见下方“业务参数表”。拼接示例如下:

    平台生成链接:
    https://open.toutiao.com/?partner=***&h5_id=1779890101120013
    
    拼接其它业务参数:
    https://open.toutiao.com/?partner=***&h5_id=1779890101120013&category=***&city=%E5%8C%97%E4%BA%AC
    

业务参数表

分组参数描述类型是否必填说明
应用参数(平台生成H5链接中自带参数)partner渠道号String登录火山引擎内容定制控制台-应用管理-查看详情,查找对应“渠道号”。
h5_id链接IDString生成的频道列表接入/分享链接唯一ID,新建接入链接时,由平台侧创建
其他参数category频道IDString即在内容定制控制台,创建频道后生成的频道ID。该参数主要用于指定H5页面加载后,进入的频道位置。默认指向场景下的首个频道。

city

城市名称

String

比如:北京,编码为utf-8。
当请求“本地”频道时,必须填入此参数,否则无法返回本地内容。目前本地频道支持的城市见“获取个性化内容”中的本地频道-城市列表说明。

客户端&H5交互

通过webview快速接入H5应用后,可以通过JSBridge进行相互之间的交互和通讯。部分接口在接入阶段必须支持,否则会影响功能的正常使用,如下文的强依赖接口。

说明

  • Android Webview 的JSBridge定义:通过“nativeBridge”对象注册JSBridge接口;
  • IOS WkWebview 的JSBridge定义:通过 registerMessageName 直接注册JSBridge接口;
  • H5应用的JSBridge函数挂载对象统一为“toutiao

强依赖接口

getAuthInfo

合作方客户端提供接口,H5应用调用该接口获取当前用户鉴权信息,实现千人千面个性化内容推荐。

接口入参:

字段类型说明是否必填
callbackApiString指定获取鉴权信息的回调方法,示例: 'window.toutiao.__callback__···'

接口返回:

字段类型说明是否必填
codeNumber接口调用结果,0代表成功,非0代表失败
messageString接口调用结果描述
datasignatureString签名信息,参见“签名机制
timestampNumber时间戳(秒),为保证安全,timestamp 与当前时间戳相关绝对值不能超过3600 秒
nonceString随机数,6-12位随机字符串
access_tokenString身份标识,wap注册接口返回的用户唯一标识

可选交互接口

jumpDetailPage

合作方客户端提供接口,H5列表页调用该接口跳转详情页,保证列表页和详情页切换时,列表页滚动位置始终为用户跳转前的位置。接口不存在时,则H5直接通过location.href进行跳转。

接口入参:

字段类型说明是否必填
dataurlString详情页访问链接
titleString详情页内容标题
abstractString详情页内容摘要
shareUrlString详情页分享链接
thumbImageString详情页封面图

switchTab

火山H5应用提供接口,客户端在用户进行左右滑动时,通过调用该接口实现多频道列表页的频道切换功能,优化用户体验。

接口入参:

字段类型说明是否必填
datacategoryString频道对应的Category值
callbackApiString获取调用结果的JSBridge接口名,客户端需要提前实现接口定义,例如“getAuthInfo”

接口返回:

字段类型说明是否必填
codeNumber接口调用结果,0代表成功,非0代表失败
messageString接口调用结果描述

refresh

火山H5应用提供接口,客户端调用该接口刷新H5列表页。如果传入category参数,刷新后,页面Tab将定位到具体频道列表上。

接口入参:

字段类型说明是否必填
datacategoryString频道对应的Category值
callbackApiString获取调用结果的JSBridge接口名,客户端需要提前实现接口定义,例如“getAuthInfo”

接口返回:

字段类型说明是否必填
codeNumber接口调用结果,0代表成功,非0代表失败
messageString接口调用结果描述

示例代码

客户端调用H5应用接口

调用“switchTab”接口切换H5列表页频道,示例代码:

webView.evaluateJavascript(
    "window.toutiao.switchTab({ data: { category: '***' } })"
) {}

客户端实现JSBridge接口

强依赖接口“getAuthInfo”的实现,示例代码(Android版):

// ...其它依赖...
import com.google.gson.Gson

// 定义JSBridge接口
public class MyJSInterface(private val webView: WebView) {
    class RequestData (
        val callbackApi: String?, // callbackApi为js回调函数,格式为:'window.toutiao.__callback__···'
    ) {}
    class ResponseData (
        val code: Number, // 响应码非0代表异常
        val message: String, // 响应结果描述
        val data: Any,
    ) {}
    @JavascriptInterface
    fun getAuthInfo(params: String) {
        val gson = Gson()
        val data = gson.fromJson(params, RequestData::class.java)
        class AuthInfo (
            val signature: String = "***",
            val timestamp: String = "***",
            val nonce: String = "***",
            val access_token: String = "***",
        ) {}
        if (data.callbackApi !== null && data.callbackApi !== "") {
            webView.post {  webView.evaluateJavascript(
                "${data.callbackApi}(${gson.toJson(ResponseData(0, "success", AuthInfo()))})"
            ){} }
        }
    }   
}

// Webview初始化支持JSBridge
class DemoFragment : Fragment() {
    // ...其它逻辑...
    
    override fun onCreateView(): View {
        val webview: WebView = _binding!!.webviewHome
        webview.apply {
            settings.javaScriptEnabled = true
            addJavascriptInterface(MyJSInterface(webview), "nativeBridge")
        }
        webview.loadUrl(config.url)

        // ...其它逻辑...
    }
}

小程序/Iframe接入列表页

const iframeDom = document.querySelector('#iframeId');
    
    const handleMessage = (event: MessageEvent) => {
      const { api, callbackApi, ...others } = event.data || {};

      switch (api) {
        case "getAuthInfo":
          /* 传递用户鉴权信息至火上H5端,用于拉取个性化推荐内容 */
          iframeDom?.contentWindow?.postMessage({
            code: 0,
            data: {
              signature: 'xxx',
              timestamp: 'xxx',
              nonce: 'xxx',
              access_token: 'xxx',
            },
            callbackApi: callbackApi,
          }, '*');
          break;
        case "jumpDetailPage":
          /* 列表页跳转详情页前,会postMessage同步客户端。如果返回code=0,则由客户侧控制详情页的跳转 */
          // others参数可参考:https://www.volcengine.com/docs/6392/1167827#jumpdetailpage
          iframeDom?.contentWindow?.postMessage({
            code: 0,
            callbackApi,
          }, '*');
          break;
        default:
          break;
      }

      if (event.data === "test") {
        console.log("test");
      }
    };
    
    window.addEventListener("message", handleMessage);