过滤原理与元素隐藏:Adblock Plus 拦截广告的两层机制
第一层:网络请求拦截
浏览器加载一个网页时,会发起成百上千个 HTTP 请求——HTML 文档、CSS、JS、图片、广告联盟脚本、跟踪像素……每一个请求的 URL 都会经过 Adblock Plus。
ABP 用"过滤规则"来判断某个 URL 是否应该被拦截。规则大致分两类:
- 地址匹配:规则写死一个 URL 片段(或通配符模式),所有匹配的请求直接被取消,浏览器收不到任何响应。
- 类型匹配:规则还可以限定请求类型,例如只拦截 JS 脚本、只拦截图片、只拦截第三方域名。
被拦截的请求在浏览器开发者工具的 Network 面板里会显示红色或"Blocked"状态。
第二层:元素隐藏
网络请求拦截解决不了两种情况:
- 广告直接嵌在 HTML 源码里(不额外发起请求);
- 广告内容是浏览器已经加载好的图片,但它的 div 容器本身就是广告位。
元素隐藏通过向页面注入 CSS 来解决。规则形如:
域名##选择器
这条规则的意思是"在 example.com 下,找到符合这个 CSS 选择器的元素,加上 display: none !important"。页面看上去这块就消失了,实际上 DOM 里还在,只是被 CSS 藏了起来。
两层配合的典型场景
YouTube 是最典型的例子:
- 视频前贴片广告大多通过独立的
googlevideo.com请求加载,第一层拦截直接掐断; - 播放界面上的推荐位、信息卡通常嵌在主页面 DOM 里,第一层拦不到,靠第二层的 CSS 选择器隐藏。
这也是为什么某些订阅列表切换后,YouTube 拦截效果差异很大——不同列表覆盖的选择器不一样。
为什么会留空白
如果第一层拦截生效,广告根本没加载,页面布局里原本该放它的位置会空出来,留一块白。这时候需要元素隐藏来补位——不仅要拦请求,还要把那个空占位的 div 也 hide 掉。好的订阅列表会两条规则一起写,新手自己写规则时常只写了第一层,拦了请求没隐藏占位。
规则执行顺序
ABP 的规则引擎执行顺序大致是:
- 所有地址匹配规则同时遍历;
- 例外规则(
@@开头)优先于拦截规则; - 元素隐藏规则在页面 DOM 加载完成后、渲染前注入。
这意味着你可以同时订阅 EasyList(大范围拦截)和自己写的 @@ 例外规则(放行某类内容),两边互不冲突。