HarmonyOS Web 智能跟踪防护(ITP)实战:一打开就“登录掉了”?这玩意儿怎么用才不坑
HarmonyOS Web 智能跟踪防护(ITP)实战:一打开就“登录掉了”?这玩意儿怎么用才不坑
鸿蒙第四期开发者活动
在 ArkTS 侧把异步逻辑包装成Promise,Native 侧拿到这个 Promise 对象,然后给它挂then / catch,在回调里获取异步结果或异常。
本文用一个完整示例,走一遍从 ArkTS 到 Native 的链路。
1. 整体思路
-
ArkTS 侧:
- 调用 Native 接口时,把一个 callback 传给 Native。
- Native 调用这个 callback,ArkTS 在 callback 里 返回一个 Promise 对象。
- Promise 内部用
setTimeout模拟异步,最终resolve或reject。
-
Native 侧:
- 通过
napi_call_function调用 ArkTS 传入的 callback,得到 Promise 对象。 - 用
napi_get_named_property拿到 Promise 的then和 `cat
- 通过
做 ArkWeb(Web 组件)到一定阶段,你迟早会碰到这种“很诡异但又很真实”的问题:
- 你把一个第三方页面嵌进 Web 里(比如广告、统计、客服、登录组件)。
- 页面能加载,但总觉得少了点啥:登录态不稳定、埋点丢失、个性化推荐变“失忆”。
- 更离谱的是:有些域名正常,有些域名怎么都不带 Cookie。
这时候,十有八九就跟 Intelligent Tracking Prevention(智能跟踪防护,简称 ITP)有关。
在 HarmonyOS 的 Web 组件里,ITP 的核心效果用一句话说就是:
当“疑似跟踪站点”作为第三方被嵌入到别的网站里时,它发起的网络请求会被限制携带 Cookie。 思相
这不是 bug,这是隐私保护策略。你要做的是:知道它在什么时候生效、怎么开关、怎么排查、以及什么时候需要“放行名单”。
1)ITP 到底在防什么?(先说人话)
ITP 主要针对的是“跨站跟踪”这类行为:
第三方资源(脚本、iframe、像素、广告组件)被插到很多站点里,通过 Cookie 等标识把用户在不同站点的行为串起来。
WebKit 体系里对 ITP 的方向很明确:减少跨站追踪、限制第三方环境下的 Cookie/站点数据使用。WebKit+1
所以你会看到典型影响:
- 第三方 Cookie 变得不好使(甚至直接被切掉)
- 依赖第三方 Cookie 的登录态、统计归因、跨域识别会受影响
2)HarmonyOS ArkWeb 里 ITP 的“触发条件”是什么?
官方/示例文档把它说得很直白:
当一个跟踪网站被作为第三方插入到另一个网页时,它发出去的请求不能携带 Cookie。 思相
翻译成人话就是:
- 你 Web 里加载了 A 网站
- A 里又嵌了 B(iframe / third-party 脚本等)
- B 这个域名如果被识别为“跟踪站点”,它的请求可能就不带 Cookie 了
这也是为什么你会觉得“有些域名正常,有些域名很怪”。
3)怎么开启/关闭 ITP(最常用的两行代码)
ArkWeb 提供了 WebviewController 级别的开关:
enableIntelligentTrackingPrevention(true/false):开启/关闭(默认是关闭) 思相isIntelligentTrackingPreventionEnabled():查询当前是否开启 思相
示例(建议你写成按钮/开关,排查时很好用):
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
controller: webview.WebviewController = new webview.WebviewController();
try {
this.controller.enableIntelligentTrackingPrevention(true);
console.info('ITP enabled');
} catch (e) {
const err = e as BusinessError;
console.error(`enable ITP failed: ${err.code}, ${err.message}`);
}
try {
const enabled = this.controller.isIntelligentTrackingPreventionEnabled();
console.info('ITP status: ' + enabled);
} catch (e) {}
我个人习惯:开发阶段先做成 UI 开关,方便你对比“开/关”时的 Cookie、登录、埋点差异——很多问题一对比就明白了。
4)怎么知道 ITP “拦了谁”?(排查神器)
你不可能靠猜。ArkWeb 提供了一个回调可以拿到 ITP 的拦截信息:
onIntelligentTrackingPreventionResult(...):异步拿到被拦截的 tracking 域名(trackerHost)和当前访问站点(host)
并且只有在 ITP 已开启时才会触发。思相
示例:
Web({ src: 'www.example.com', controller: this.controller })
.onIntelligentTrackingPreventionResult((details) => {
console.info(`ITP hit: websiteHost=${details.host}, trackerHost=${details.trackerHost}`);
});
这段日志非常关键:
你会直观看到“到底是哪个第三方域被当成 tracker 了”,从而决定后续是改业务还是放行。
5)什么时候需要“放行名单”?(别一刀切)
现实很残酷:有些第三方确实是“跟踪”,但你业务又确实要用,比如:
- 合规的登录/单点组件(嵌入式)
- 必要的支付/风控组件
- 企业内部统计/监控(你自己家的,但域名是第三方形态)
ArkWeb 提供了 ITP 绕过名单(Bypassing List),而且有个非常容易忽略的点:
这个名单是“全应用级别”的,不是单个 Web 组件级别。 思相
也就是说:你一旦把某个域名加进放行名单,可能会影响 App 里所有 Web 页面。所以别乱加,最好只加你完全信任且必须放行的域名。
相关 API(示例文档里给得很清楚):
addIntelligentTrackingPreventionBypassingList(hostList):添加放行域名列表 思相removeIntelligentTrackingPreventionBypassingList(hostList):移除部分放行域名 思相clearIntelligentTrackingPreventionBypassingList():清空放行名单 思相
示例:
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
try {
const hostList = ['www.test1.com', 'www.test2.com'];
webview.WebviewController.addIntelligentTrackingPreventionBypassingList(hostList);
} catch (e) {
const err = e as BusinessError;
console.error(`add bypass list failed: ${err.code}, ${err.message}`);
}
6)我建议你用一套“很稳的上线策略”(减少踩坑)
如果你是做真实业务,我会建议你按这个顺序来:
- 默认先不开 ITP(跟着默认值走),把功能跑通(登录、统计、支付等)
- 打开 ITP,观察:
- 哪些第三方域开始“掉 Cookie / 掉登录态”
onIntelligentTrackingPreventionResult打出来的 trackerHost 是谁 思相
- 决策:
- 能不用的第三方:就别用(隐私/合规也更舒服)
- 必须用且可信:再进放行名单(并记录原因)
- 放行名单一定要:
- 最小化(只加必要域名)
- 可回滚(提供 remove/clear 的配置开关) 思相
7)写在最后:ITP 不是“麻烦”,它是在逼你把边界想清楚
ITP 的存在,其实是在提醒我们:
“第三方嵌入拿用户 Cookie 做跨站识别”这件事,本身就是高风险动作。
你作为开发者,最舒服的姿势不是“把 ITP 关掉”,而是:
- 该保护的就保护(ITP 开着)
- 该放行的明确放行(名单最小化)
- 可观测、可回滚(日志 + 配置)

浙公网安备 33010602011771号