欢迎光临
我们一直在努力

HarmonyOS ArkWeb 系列之 广告过滤:AdsBlockManager 从入门到精细控制

文章目录

      • 广告过滤的工作原理
      • 第一步:加载规则文件
      • 开启广告过滤的正确时机
      • 精细控制:域名级别开关
      • 监听广告拦截数据
      • AdsBlockManager API 速查
      • 域名匹配规则说明
      • 写在最后

浏览器内嵌页面广告太多?ArkWeb 提供了 AdsBlockManager 和 enableAdsBlock 接口,让你给 Web 组件加上广告拦截功能。更重要的是,它支持域名级别的精细控制——某些网站的广告不拦截,某些子域名单独配置。

广告过滤的工作原理

广告过滤基于规则文件(EasyList 格式),规则文件里定义了哪些请求 URL 是广告请求。Web 组件加载页面时,每次网络请求都会对照规则文件,匹配上的请求直接拦截,广告资源就不会加载。

第一步:加载规则文件

广告过滤需要先加载规则文件。规则文件格式兼容 EasyList(开源广告过滤规则,全球通用)。

import { webview } from '@kit.ArkWeb';
import { picker } from '@kit.CoreFileKit';

@Entry
@Component
struct AdsBlockSetupDemo {
controller: webview.WebviewController = new webview.WebviewController();

build() {
Column({ space: 12 }) {
// 从文件选择器选取规则文件
Button('选择广告过滤规则文件')
.onClick(async () => {
try {
// 弹出文件选择器,让用户选择规则文件
const docPicker = new picker.DocumentViewPicker(
this.getUIContext().getHostContext()!
);
const result = await docPicker.select({
maxSelectNumber: 1,
// 可以限制文件类型
});

if (result.length > 0) {
const ruleFilePath = result[0];
console.info('选择的规则文件:', ruleFilePath);

// 加载规则文件(全局生效)
webview.AdsBlockManager.setAdsBlockRules(ruleFilePath, true);
}
} catch (error) {
console.error('选择文件失败:', error);
}
})

Web({ src: 'https://www.example.com', controller: this.controller })
.width('100%')
.layoutWeight(1)
.onControllerAttached(() => {
// 控制器就绪后开启广告过滤
this.controller.enableAdsBlock(true);
})
}
.width('100%')
.height('100%')
.padding(16)
}
}

开启广告过滤的正确时机

enableAdsBlock 必须在控制器就绪(onControllerAttached)之后调用:

Web({ src: 'https://www.example.com', controller: this.controller })
.onControllerAttached(() => {
// 正确:在这里调用
this.controller.enableAdsBlock(true);
})

不要在组件创建时直接调,那时候控制器还没初始化完。

精细控制:域名级别开关

光是全局开关还不够用,有时候你需要:

  • 这个网站整体不过滤(用户付费网站,去掉广告会影响使用)
  • 某个子域名单独过滤/不过滤

方案一:不过滤指定域名(DisallowedList)

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct AdsBlockDisallowedDemo {
controller: webview.WebviewController = new webview.WebviewController();
@State urlInput: string = 'https://www.example.com';

build() {
Column({ space: 12 }) {
// URL 输入框
Row() {
TextInput({
text: this.urlInput,
placeholder: '输入网址'
})
.layoutWeight(1)
.height(40)
.onChange((value: string) => {
this.urlInput = value;
})

Button('跳转')
.height(40)
.onClick(() => {
this.controller.loadUrl(this.urlInput);
})
}

// 将当前域名加入"不过滤"列表
Button('对该域名不过滤广告')
.onClick(() => {
// 传入域名后缀数组(不是完整 URL)
const domains = ['example.com', 'trusted-news.cn'];
webview.AdsBlockManager.addAdsBlockDisallowedList(domains);
console.info('已加入不过滤列表:', domains);
})

Web({ src: 'https://www.example.com', controller: this.controller })
.width('100%')
.layoutWeight(1)
.onControllerAttached(() => {
this.controller.enableAdsBlock(true);
})
}
.width('100%')
.height('100%')
.padding(16)
}
}

方案二:AllowedList + DisallowedList 配合,实现子域名级别控制

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct AdsBlockSubdomainDemo {
controller: webview.WebviewController = new webview.WebviewController();

build() {
Column({ space: 12 }) {
Button('配置子域名过滤策略')
.onClick(() => {
// 先把主域名加入"不过滤"列表
// example.com 的广告不拦截
webview.AdsBlockManager.addAdsBlockDisallowedList(['example.com']);

// 再把子域名加入"允许过滤"列表
// news.example.com 和 sport.example.com 子域名要拦截广告
webview.AdsBlockManager.addAdsBlockAllowedList([
'news.example.com',
'sport.example.com'
]);

// 结果:
// – www.example.com → 不过滤
// – news.example.com → 过滤广告
// – sport.example.com → 过滤广告
// – blog.example.com → 不过滤(继承主域名规则)
console.info('子域名级别广告过滤策略已配置');
})

Web({ src: 'https://www.example.com', controller: this.controller })
.width('100%')
.layoutWeight(1)
.onControllerAttached(() => {
this.controller.enableAdsBlock(true);
})
}
.width('100%')
.height('100%')
.padding(16)
}
}

监听广告拦截数据

通过 onAdsBlocked 回调可以知道每次哪些广告被拦截了:

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct AdsBlockStatsDemo {
controller: webview.WebviewController = new webview.WebviewController();

@State totalBlocked: number = 0;
// 已统计过的 URL,避免重复计数
private blockedSet: Set<string> = new Set();

build() {
Column({ space: 8 }) {
Text(`今日已拦截广告:${this.totalBlocked}`)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor(Color.Orange)

Web({ src: 'https://www.example.com', controller: this.controller })
.width('100%')
.layoutWeight(1)
.onControllerAttached(() => {
this.controller.enableAdsBlock(true);
})
.onAdsBlocked((details) => {
// details.url:当前页面 URL
// details.adsBlocked:被拦截的广告 URL 数组
if (details.adsBlocked && details.adsBlocked.length > 0) {
details.adsBlocked.forEach((adUrl: string) => {
if (!this.blockedSet.has(adUrl)) {
this.blockedSet.add(adUrl);
this.totalBlocked += 1;
console.info('拦截广告:', adUrl);
}
});
}
})
}
.width('100%')
.height('100%')
.padding(16)
}
}

AdsBlockManager API 速查

方法说明
AdsBlockManager.setAdsBlockRules(path, isReplace) 设置规则文件路径,isReplace=true 替换已有规则
controller.enableAdsBlock(true/false) 开启/关闭当前 Web 实例的广告过滤
AdsBlockManager.addAdsBlockAllowedList(domains) 添加"允许过滤"域名(在 disallowed 基础上例外)
AdsBlockManager.addAdsBlockDisallowedList(domains) 添加"不过滤"域名
AdsBlockManager.removeAdsBlockAllowedList(domains) 移除"允许过滤"域名
AdsBlockManager.removeAdsBlockDisallowedList(domains) 移除"不过滤"域名
AdsBlockManager.clearAdsBlockAllowedList() 清空"允许过滤"列表
AdsBlockManager.clearAdsBlockDisallowedList() 清空"不过滤"列表

域名匹配规则说明

传入的域名是后缀匹配:

  • example.com 会匹配 www.example.com、news.example.com 等所有子域名
  • news.example.com 只匹配该子域名本身

AllowedList 的优先级高于 DisallowedList——如果一个域名同时在两个列表里,AllowedList 生效(即会过滤广告)。

写在最后

广告过滤功能对内容浏览类 App 提升体验非常明显。AllowedList + DisallowedList 的组合设计很灵活,可以做到主域名免过滤、特定子域名单独控制。记得先加载规则文件,规则文件质量决定拦截效果,EasyList 是目前社区最广泛使用的。

赞(0)
未经允许不得转载:171主机测评 » HarmonyOS ArkWeb 系列之 广告过滤:AdsBlockManager 从入门到精细控制
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址