文章目录
-
-
- 广告过滤的工作原理
- 第一步:加载规则文件
- 开启广告过滤的正确时机
- 精细控制:域名级别开关
- 监听广告拦截数据
- 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 是目前社区最广泛使用的。



