内容拦截

内容已过时。

Focus 使用与桌面版 Firefox 相同的技术,所有内容拦截都在 Gecko 引擎网页引擎内部进行。内容拦截列表可以在此处查看 https://github.com/mozilla-services/shavar-prod-lists。

跟踪保护:列表和概述

我们使用 Disconnect 跟踪保护列表,这些列表包含:

  • 拒绝列表:要阻止的域列表。

  • 实体列表:用于解除某些域对某些其他域的阻止的覆盖列表。

  • google_mapping:拒绝列表的修改列表。

拒绝列表

拒绝列表包含应阻止的域列表。托管在这些域上的任何资源都应被阻止。

源列表包含多个类别,我们使用**广告**、**社交**、**分析**、**内容**(又名“其他内容跟踪器”)。我们使用 Disconnect 列表中的某些项目,在解析时,这些项目会被移动到**社交**列表中。我们忽略**旧版 Disconnect** 和**旧版社交**。您可以在BlockListProcessor.java中看到解析这些列表的代码。

google_mapping 与主列表类似 - 这些项目只是简单地添加到上面提到的现有类别中。(我们丢弃主**Disconnect** 列表中的 Google 条目,因为我们使用来自 google_mapping.json 的条目。)

注意:每个类别都包含站点所有者列表:这些名称会被丢弃,我们将每个所有者的每个域都插入到同一个列表中。

实体列表:覆盖列表

访问属于同一所有者的另一个域时,需要解除某些域的阻止。例如,我们通常会阻止“googleapis.com”,但在访问例如 google.de 时,我们会解除“googleapis.com”的阻止。这是在实体列表中完成的:对于属于实体列表中“属性”的每个域,我们都会解除“资源”中列出的所有域的阻止。

实现

每次要加载资源时,WebView 都会调用 WebViewClient.shouldInterceptRequest() 回调 - 这允许我们拦截资源加载,并且是我们在 Android 上执行内容拦截的方式。(参见BlockListProcessor.java)。

然后,我们只需要验证每个资源 URL 以确定是否可以在该回调中加载它:我们对 Android 版 Focus 使用自定义的基于 Trie 的域匹配实现。这与 Focus iOS 不同:Focus for iOS 最初是一个内容拦截 Safari 插件,并使用了 iOS 内容拦截 API(https://developer.apple.com/library/content/documentation/Extensions/Conceptual/ContentBlockingRules/Introduction/Introduction.html)。该 API 使用特定的黑名单格式,因此 firefox-ios 在构建时将 Disconnect 列表转换为 iOS 格式。

Focus-ios 浏览器后来才实现,并重新使用 iOS 内容拦截列表格式(当时 iOS webview 无法使用内容拦截 API,因此实现了它自己的 URL 匹配)。这是一种基于正则表达式的格式:因此,Focus-ios(浏览器)存储了一个正则表达式列表,并迭代该列表以检查给定的资源 URL 是否匹配。这种方法意味着 Focus-ios 只需要一份黑名单副本,但这对于性能来说并不理想。

如前所述,Android 版 Focus 使用自定义的 Trie 实现,而不是迭代正则表达式。这确实意味着我们没有重复使用 iOS 的黑名单格式,但它也使与 iOS 域查找实现的移植相比,域查找速度提高了约 140 倍。实体列表与此类似,我们对域覆盖使用相同 Trie 的扩展版本。有关实际匹配器实现,请参见UrlMatcher

其他说明

  • 我们不进行任何互联网连接,因为每个黑名单都内置在 Firefox Focus 中。当您在设置中启用黑名单时,我们的应用程序将从磁盘加载选定的黑名单。我们将提供更新的列表作为“应用更新”。

  • 在解析黑名单时,我们丢弃站点所有者和名称,这使得难以跟踪哪些跟踪器已被阻止。如果我们希望更好地细分跟踪器,则可能必须将这些数据添加到黑名单 Trie 中。

  • 我们的 Trie 搜索是递归的,并使用略微愚蠢的“TrieString”来处理字符串反转和子字符串。迭代实现可能会更好,并且可以避免子字符串。这样的实现会稍微复杂一些,因为我们必须跟踪字符串索引,但可以减少开销。鉴于当前性能是可以接受的,因此实际处理此问题并没有太大的价值。