常见问题 - Adblock Plus 内部详情

我该如何了解 Adblock Plus 所有首选项的含义?

  Adblock Plus 在 about:config 中包含一系列以 extensions.adblockplus. 打头的首选项。(这有别于 Adblock 和 Adblock Plus 0.5 的首选项以 adblock. 打头)。 所有的首选项及其解释可以在这里查阅。

我该如何让我的扩展接入 Adblock Plus?

  通过 IAdblockPlus 接口的输出,其他扩展可以集成到 Adblock Plus。详情请参阅接口文档

Adblock Plus 是怎么过滤地址的?

  实际上最难的事情是由 Firefox、Thunderbird 及其他应用程序所基于的底层引擎 — Gecko 来完成的。它支持一种称为 "内容策略(content policies)"的机制。所谓的内容策略简单来说就是一个 JavaScript(或 C++)对象,浏览器一旦需要加载内容就必须调用它。此时它会根据地址和其他数据来判断是否加载这些内容。Gecko 引擎内置了一些内容策略(当你在 Firefox 或者 Seamonkey 中定义哪些站点不允许加载图片的时候,实际上就是配置了一个内置的内容策略),任何扩展都可以注册自己的内容策略。因此,Adblock Plus 要做的就是注册自己的内容策略,剩下的就只有定义哪些地址需要被阻挡的程序逻辑和配置过滤规则的用户界面了。

  对于开发人员来说,要注册一个内容策略,您编写的 XPCOM 组件需要实现 nsIContentPolicy 接口。通过模块的 registerSelf 方法在"内容策略"分类中注册您的组件(使用 category manager 来实现)。然后,您就可以通过调用 shouldLoad 方法来决定是否接受指定的请求。

Adblock Plus 是怎么处理过滤规则的,什么样的规则处理得更快?

  所有的过滤规则都会在内部转换为正则表达式,包括那些简单规则。例如,ad*banner.gif| 会被转换为 /ad.*banner\.gif$/。Adblock Plus 在处理给定地址时需要校验所有过滤规则,但此时它并不会简单地一条接着一条校验,因为这无疑会拖慢浏览速度。

  除了转换过滤规则为正则表达式之外,Adblock Plus 还会尝试提取其中的文本信息得到唯一一个 8 字符的字符串(称为"快捷方式,shortcut")。该字符串必须包含在每个匹配过滤规则的地址中(其实字符串长度可以是任意的,只是这里 8 字符最合理)。举例来说,对于过滤规则 |http://ad.*,Adblock Plus 可以选择 "http://a"、"ttp://ad" 或是 "tp://ad.",这些字符串都包含在这条规则匹配的地址中。可惜的是目前我们还无法为不满足连续 8 个字符(不含通配符)的简单规则和正则表达式指定“快捷方式”。

  所有快捷方式都存放在一个可查找的表中,Adblock Plus 可以通过快捷方式非常高效地查找到相应的规则。Adblock Plus 处理指定的地址时首先会查找这个表(查找速度非常快,几乎和快捷方式的数量无关)。只有匹配到快捷方式后才会应用相应的规则。处理没有快捷方式的规则(称为"慢速规则")时,则需要对所有过滤规则一条一条地匹配。

  总结: 什么样的过滤规则处理速度更快?尽量少使用处理速度较慢的正则表达式,同时保证简单规则至少包含 8 个连续字符(这里所说的"连续"是指不含 * 这样的特殊字符),否则等同于处理速度较慢的正则表达式。但只要简单规则符合要求,其处理时间都是一样的,与规则数量多少无关。这意味着就算您用 20 条简单规则代替一条正则表达式都是值得的。说到这里,建议使用这个小工具转换正则表达式为简单规则。

点击这里查阅详细的过滤规则匹配算法

元素隐藏功能是怎么实现的?

  元素隐藏规则会被转换为 CSS 并应用到所有用户正在访问的网页。像是 example.com#div(evil_ad) 这条规则会被转换为:

@-moz-document domain(example.com)
{
  div#evil_ad, div.evil_ad
  {
    display: none !important;
  }
}

  @-moz-document 是一个 CSS 标准的推荐扩展规则,您可以查阅 Mozilla 开发者中心

  对于那些没有指定域名的规则会按照 http:// 和 https:// 进行处理,防止这些规则应用到浏览器的用户界面(它使用的是 chrome:// 协议模型)。例如,#div(evil_ad) 这条规则会被转换为:

@-moz-document url-prefix(http://),url-prefix(https://)
{
  div#evil_ad, div.evil_ad
  {
    display: none !important;
  }
}

  对于开发人员来说, Adblock Plus 使用的是这个样式表服务实现元素隐藏功能。这个接口是在 Gecko 1.8 时引入的,它允许扩展动态加载用户自定义 CSS(在此之前只能通过修改 userContent.css 并重启浏览器才能生效)。用户自定义 CSS 会覆盖所有网站的 CSS 代码,因为它具有最高的优先级

过滤规则订阅多久自动更新一次?

  过滤规则订阅默认每天更新一次。但订阅列表作者也可以自行调整这个值,例如出于防止浪费流量方面的考虑。调整范围包括每小时到每隔 21 天。其中一种实现方法是设置 HTTP Expires header,比如在 Apache mod_expires 模块的 .htaccess 文件中添加以下语句:

ExpiresActive on
ExpiresByType text/plain "access plus 5 days"

  这样过滤规则列表会在下载的 5 天后显示为过期。对于用 Perl 脚本编写的过滤规则列表,您可以添加以下命令达到相同效果:

$cgi->header(-expires => "+5d");

  上述代码也适用于其他脚本语言,例如 PHP。如果由于某种原因无法修改 HTTP header,您也可以在过滤规则列表添加类似下面的注释:

[Adblock]
! This list expires after 5 days

  上面的注释可以放在列表任何位置,因为 Adblock Plus 会在所有注释中查找 "expires after" 或 "expires:" 加上一个数字这样的关键词。默认这个数字会被视作更新失效的天数,而数字之后的字母 "h" 则视作小时。例如,"Expires: 3h" 或 "expires after 3 hours" 将会告知 Adblock Plus 在 3 小时后自动重新下载过滤规则列表。

  请注意这是两次下载间隔的最少时间,只有在用户打开浏览器的情况下间隔时间到后才会重新下载过滤规则。

我的过滤规则订阅地址已变更,我该怎么保证所有用户都能正确更新?

  Adblock Plus 0.7.5 开始就完全支持永久重定向了。这意味着不仅订阅会从新的地址下载,Adblock Plus 中的订阅地址也会修改,这样以后的下载会立即使用新的地址。如何使用这个新特性呢?

  第一选择:利用 HTTP 标头重定向。对旧的规则列表地址的请求应该返回 “301 永久移动”的响应。Adblock Plus 会在重定向成功后修正订阅地址。您可以使用 Apache 的 mod_alias 模块创建这样的一个重定向示例。添加类似下面的一行到您的 .htaccess 文件中:

Redirect permanent /old_list.txt http://example.com/new_list.txt

  如果在您的主机上您不能创建一个 HTTP 重定向,您依然可以使用一个特殊注释来指定订阅列表的新地址。它看起来类似这样的:

[Adblock]
! Redirect: http://example.com/new_list.txt

  这个注释可以在您规则列表的任何地方,Adblock Plus 会扫描所有的注释找出 关键字 "redirect:" 和 "redirect to" 后跟的地址。如果找到这样的注释,新的订阅会立即更新。一个小时后, 新的地址应该会更新成功的,订阅列表的地址也将得到调整。

  最后,这可能发生在您的服务器不可用和用户在每次订阅该更新都下载错误的情况下。甚至假设您也无法预防这个错误,依然还有一个解决方案。在多次下载失败后(取决于 extensions. adblockplus. subscriptions_fallbackerrors)。Adblock Plus 会联系 extensions. adblockplus. subscriptions_fallbackurl 中定义的地址要求进一步说明。如果确定是这个地址的问题,就需要修改您订阅列表的地址。如果您不能通过常规手段修改您的订阅地址,请发邮件

过滤规则文件的第一行表示什么?

  过滤规则文件的第一行通常都是 [Adblock]。但您可能发现在最近版本的 Adblock Plus 中过滤文件第一行有时显示为其他文字,这是由于您列表中部分过滤规则的语法只支持新版本 Adblock Plus 而不支持早期的 Adblock。例如:

(Adblock Plus 0.6.1.2 or higher required) [Adblock]

  这里括号中的内容只是一个注释,Adblock 或 Adblock Plus 读取时会忽略实际标记之前的任何内容。由于 Adblock Plus 0.6.1.2 还不支持这种写法,因此这里 Adblock Plus 不会强制要求用户更新到新版本。然而,如果您使用更加新的过滤规则语法,则第一行有可能会变成:

[Adblock Plus 0.7.1]

  上面这种写法是从 Adblock Plus 0.7.1 开始支持的,而之前版本的 Adblock Plus 以及 Adblock 则无法打开这种文件。Adblock Plus 会将文件第一行的版本号和扩展自身版本号进行比较,如果文件要求的版本号高于扩展当前版本号,则 Adblock Plus 会提示用户更新到新版本。对于过滤规则订阅,它仍会加载这个文件,但会在首选项对话框显示扩展更新提示。

  最后,如果只想兼容 Adblock Plus 但不在乎其版本号,您可以将文件第一行修改为 [Adblock Plus]。当然这样的过滤规则文件只支持 Adblock Plus 0.7.1 及更高版本。

如何避免我的过滤规则订阅出现偶尔下载后损坏的情况?

  代理服务器以及反病毒和防火墙软件有可能会修改下载的过滤规则,使得有时过滤规则 "*/example/*" 变成了 "**",从而导致所有网页内容都被过滤。要解决这个问题订阅维护人员可以在规则列表的开始部分插入一个校验和,例如:

[Adblock]
! Checksum: OaopkIiiAl77sSHk/VAWDA
test

  如果校验和与文件内容不一致,Adblock Plus 将不会下载这些过滤规则,而导出过滤规则时 Adblock Plus 也会自动创建校验和,它的生成方式如下:

  • 过滤规则列表采用 UTF-8 编码(包括第一行
  • 所有换行符转换为 UNIX 风格(如果存在 \r 则删除)
  • 删除空白行(多个 \n 替换为一个 \n)
  • 删除已有的校验和注释
  • 生成一个 base64 编码的 MD5 校验文本(如果结尾处有 =,则全部删除)

  Perl 代码实现如下(假定文件编码是 UTF-8):

use Digest::MD5 qw(md5_base64);

my $data = readFile($file);

# 数据标准化
$data =~ s/\r//g;
$data =~ s/\n+/\n/g;

# 删除已有校验和
$data =~ s/^\s*!\s*checksum[\s\-:]+[\w\+\/=]+.*\n//mi;

# 生成新的校验和
my $checksum = md5_base64($data);

参考文献:验证校验和文件添加校验和

  PHP 代码实现如下(假定文件编码是 UTF-8):

$data = file_get_contents($file);

# 数据标准化
$data = preg_replace('/\r/', '', $data);
$data = preg_replace('/\n+/', "\n", $data);

# 删除已有校验和
$data = preg_replace('/^\s*!\s*checksum[\s\-:]+([\w\+\/=]+).*\n/mi', '', $data);

# 生成新的校验和
$checksum = base64_encode(pack('H*', md5($data)));
$checksum = preg_replace('/=+$/', '', $checksum);
Powered by Anwiki关于 Adblock Plus隐私策略Impressum