火山引擎内容定制H5应用是以移动H5页面为载体,具有个性化推荐能力的应用。客户侧研发仅需要将获取到的H5地址拼接业务参数后,嵌入到自身产品业务入口中即可,帮助您实现接入的高效率、低成本。
对比项 | H5接入 | API接入 |
---|---|---|
适用场景 | 产研资源有限,需要快速接入定制产品,完成基础功能的搭建 | 产研资源充足,需要在c端呈现完整的产品功能,用户体验要求高 |
用户体验 | 交互样式相对单一 | 交互样式可自定义 |
接入成本 | 低(H5链接的拼接和鉴权,预计开发时间为1周) | 高(ui设计,前端样式开发,服务端接口对接,预计开发时间为1-2月) |
前端样式 | 多tab信息流、双feed信息流、伪沉浸式 | 多tab信息流、单列表信息流、双feed信息流、宫格、卡片(单卡片、1.4卡片、2.4卡片)、沉浸式 |
内容体裁 | 图文、横版短视频、小视频 | 图文、横版短视频、竖版小视频 |
频道类型 | 自定义频道、标准频道(含本地频道) | 自定义频道、标准频道(含本地频道)、关注频道 |
频道推荐方式 | 个性化推荐、时间倒序、热度推荐 | 个性化推荐、时间倒序、热度推荐 |
运营规则 | 置顶、屏蔽 | 置顶、屏蔽 |
互动功能 | 分享、展示评论 | 分享、展示评论、点赞、收藏(列表页、详情页都可支持) |
基础功能 | 相关推荐、阅读量 | 相关推荐、阅读量、页面UI自定义 |
作者主页 | 支持 | 支持 |
关注 | 不支持 | 支持 |
商品推广 | 不支持 | 支持 |
推送(push) | 不支持 | 支持 |
专题 | 不支持 | 支持 |
频道类型 | DEMO演示 | 图文频道 | 横版短视频频道 | 竖版小视频频道 | 图文和视频混排频道 | 短视频和小视频混排频道 |
---|---|---|---|---|---|---|
列表页样式 |
|
|
|
|
| |
列表页显示元素 | -- |
|
|
|
|
|
步骤 | 描述 |
---|---|
准备工作 |
|
创建H5链接 |
|
应用接入 |
|
业务参数表
分组 | 参数 | 描述 | 类型 | 是否必填 | 说明 |
---|---|---|---|---|---|
应用参数(平台生成H5链接中自带参数) | partner | 渠道号 | String | 是 | 登录火山引擎内容定制控制台-应用管理-查看详情,查找对应“渠道号”。 |
h5_id | 链接ID | String | 是 | 生成的频道列表接入/分享链接唯一ID,新建接入链接时,由平台侧创建 | |
其他参数 | category | 频道ID | String | 否 | 即在内容定制控制台,创建频道后生成的频道ID。该参数主要用于指定H5页面加载后,进入的频道位置。默认指向场景下的首个频道。 |
city | 城市名称 | String | 否 | 比如:北京,编码为utf-8。 |
通过webview快速接入H5应用后,可以通过JSBridge进行相互之间的交互和通讯。部分接口在接入阶段必须支持,否则会影响功能的正常使用,如下文的强依赖接口。
说明
合作方客户端提供接口,H5应用调用该接口获取当前用户鉴权信息,实现千人千面个性化内容推荐。
接口入参:
字段 | 类型 | 说明 | 是否必填 |
---|---|---|---|
callbackApi | String | 指定获取鉴权信息的回调方法,示例: 'window.toutiao.__callback__···' | 是 |
接口返回:
字段 | 类型 | 说明 | 是否必填 | |
---|---|---|---|---|
code | Number | 接口调用结果,0代表成功,非0代表失败 | 是 | |
message | String | 接口调用结果描述 | 否 | |
data | signature | String | 签名信息,参见“签名机制” | 是 |
timestamp | Number | 时间戳(秒),为保证安全,timestamp 与当前时间戳相关绝对值不能超过3600 秒 | 是 | |
nonce | String | 随机数,6-12位随机字符串 | 是 | |
access_token | String | 身份标识,wap注册接口返回的用户唯一标识 | 是 |
合作方客户端提供接口,H5列表页调用该接口跳转详情页,保证列表页和详情页切换时,列表页滚动位置始终为用户跳转前的位置。接口不存在时,则H5直接通过location.href进行跳转。
接口入参:
字段 | 类型 | 说明 | 是否必填 | |
---|---|---|---|---|
data | url | String | 详情页访问链接 | 是 |
title | String | 详情页内容标题 | 是 | |
abstract | String | 详情页内容摘要 | 是 | |
shareUrl | String | 详情页分享链接 | 是 | |
thumbImage | String | 详情页封面图 | 否 |
火山H5应用提供接口,客户端在用户进行左右滑动时,通过调用该接口实现多频道列表页的频道切换功能,优化用户体验。
接口入参:
字段 | 类型 | 说明 | 是否必填 | |
---|---|---|---|---|
data | category | String | 频道对应的Category值 | 是 |
callbackApi | String | 获取调用结果的JSBridge接口名,客户端需要提前实现接口定义,例如“getAuthInfo” | 否 |
接口返回:
字段 | 类型 | 说明 | 是否必填 | |
---|---|---|---|---|
code | Number | 接口调用结果,0代表成功,非0代表失败 | 是 | |
message | String | 接口调用结果描述 | 否 |
火山H5应用提供接口,客户端调用该接口刷新H5列表页。如果传入category参数,刷新后,页面Tab将定位到具体频道列表上。
接口入参:
字段 | 类型 | 说明 | 是否必填 | |
---|---|---|---|---|
data | category | String | 频道对应的Category值 | 否 |
callbackApi | String | 获取调用结果的JSBridge接口名,客户端需要提前实现接口定义,例如“getAuthInfo” | 否 |
接口返回:
字段 | 类型 | 说明 | 是否必填 | |
---|---|---|---|---|
code | Number | 接口调用结果,0代表成功,非0代表失败 | 是 | |
message | String | 接口调用结果描述 | 否 |
调用“switchTab”接口切换H5列表页频道,示例代码:
webView.evaluateJavascript( "window.toutiao.switchTab({ data: { category: '***' } })" ) {}
强依赖接口“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) // ...其它逻辑... } }
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);