如何在Chrome扩展中用EasyList结合declarativeNetRequest实现广告拦截
实现Chrome扩展用EasyList拦截广告(declarativeNetRequest版)
你已经走对了方向——用declarativeNetRequest实现广告拦截比传统webRequest更高效,还能避开不少性能问题。下面我会针对你遇到的两个问题给出具体解决方案和代码示例:
一、清理EasyList中的无效内容
你获取的easylist_adservers.txt里包含注释、规则后缀(比如$third-party),这些都需要过滤才能转换成有效的declarativeNetRequest规则。我们可以通过字符串处理+正则完成清理:
清理逻辑步骤:
- 按行分割内容:把返回的文本按换行符拆分成数组,逐行处理
- 过滤注释行:去掉以
!开头的注释行(包括你提到的! Third-party这类) - 移除规则后缀:去掉每行末尾以
$开头的参数(比如$third-party、$script等) - 过滤空行:清理后可能出现的空白行一并去掉
代码实现:
let adsBlacklist = []; // 注意:要使用GitHub的raw链接获取纯文本,之前的网页链接返回的是HTML axios.get('https://github.com/easylist/easylist/raw/master/easylist/easylist_adservers.txt') .then((response) => { // 1. 按行分割内容 const lines = response.data.split('\n'); // 2. 逐行过滤和处理 adsBlacklist = lines.filter(line => { const trimmedLine = line.trim(); // 过滤空行和注释行 return trimmedLine && !trimmedLine.startsWith('!'); }).map(line => { // 3. 移除$开头的规则后缀 const ruleWithoutSuffix = line.split('$')[0].trim(); // 保留EasyList原生语法(比如||、^),declarativeNetRequest支持这些语法 return ruleWithoutSuffix; }); console.log('清理后的有效规则数量:', adsBlacklist.length); // 调用规则生成函数 generateDynamicRules(adsBlacklist); }) .catch(err => { console.error('获取EasyList失败:', err); });
二、转换为declarativeNetRequest动态规则
Chrome的declarativeNetRequest.updateDynamicRules方法可以动态添加/替换规则,不用提前写死在ads_rules.json里。我们需要把清理后的每个URL转换成符合格式的规则对象,再批量提交。
规则转换要点:
- 规则ID:每个规则需要唯一ID,用递增数字生成即可
- 优先级:设为1即可(后续有其他规则可调整优先级)
- Action:类型设为
"block",实现请求拦截 - Condition:
urlFilter:直接用清理后的EasyList规则(比如||01dbf3a452b6.com^),declarativeNetRequest支持Adblock Plus的部分语法domains:设为["<all_urls>"],表示在所有网站生效resourceTypes:覆盖广告常见的资源类型,避免漏掉广告请求
代码实现:
function generateDynamicRules(cleanedRules) { // 生成规则数组 const dynamicRules = cleanedRules.map((rule, index) => ({ id: index + 1, // 唯一ID,从1开始递增 priority: 1, action: { type: "block" }, condition: { urlFilter: rule, domains: ["<all_urls>"], resourceTypes: [ "main_frame", "sub_frame", "script", "image", "stylesheet", "xmlhttprequest", "font", "media" ] } })); // 先清除已有动态规则(避免重复添加),再批量添加新规则 chrome.declarativeNetRequest.updateDynamicRules({ removeRuleIds: dynamicRules.map(rule => rule.id), addRules: dynamicRules }, () => { if (chrome.runtime.lastError) { console.error('更新动态规则失败:', chrome.runtime.lastError); } else { console.log('动态规则添加成功,共添加', dynamicRules.length, '条规则'); } }); }
额外注意事项:
- 权限与版本:你的manifest已添加
declarativeNetRequest权限,Chrome 84+支持该API在manifest v2中使用 - 规则数量限制:Chrome动态规则上限为30000条,
easylist_adservers.txt的规则数在几千条,完全符合要求 - 缓存优化:不要频繁拉取EasyList,建议本地缓存,每周更新一次,减少服务器压力并提升扩展性能
内容的提问来源于stack exchange,提问作者nukiko12
相关产品推荐
相关产品推荐

