BlockIt - Chrome 扩展程序,用于阻止请求
阻止 Chrome 浏览器中选定主机的扩展
引言
每当我们浏览网站时,后台都会发出许多请求来获取所有内容。其中一些请求很重要,而另一些则可以避免,因为它们可能是为了获取广告或推荐等。在本文中,我将尝试创建一个扩展程序,帮助屏蔽和取消屏蔽选定的 URL。
但它不会告诉你屏蔽什么。
背景
我注意到,对于某些网站,即使我安装了 AdBlock 扩展程序,仍然会显示广告。这些网站向广告提供商发送单独的请求,但由于某种原因 AdBlock 无法捕获。一种解决方法是(在 Windows 上)将条目添加到 host 文件,但我发现这很麻烦。因此,我阅读了有关 Chrome 扩展程序的知识,并尝试自己创建一个。
免责声明
- Chrome API 自编写代码以来可能已发生更改。请参考 Google 的文档以获取最新信息
- 此扩展程序已在 64 位 Windows 10 和 Chrome 版本 57.0.2987.133 上进行了测试
- 此扩展程序**不**在 Google Play 商店/网络商店中提供。
Using the Code
您只需要一个文本编辑器和安装在计算机上的 Chrome 即可查看/修改代码。
Chrome 扩展程序至少包含以下四个部分
- Manifest.json 文件
- HTML 页面
- CSS 文件
- Javascript 文件
Manifest 文件
Manifest 文件可以被认为是扩展程序的定义。它是一个简单的 JSON 文件,具有预定义的属性,这些属性告诉浏览器有关扩展程序的信息。除其他详细信息外,它还有助于设置扩展程序的名称、版本、描述、权限、用户界面以及与之关联的 JS 文件。
此扩展程序的 Manifest 文件如下所示
{ "manifest_version": 2, "name": "BlockIt", "description": "Blocks a website domain for you in Chrome. All your settings will be synchronized if it is enabled in Chrome", "version": "1.0", "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "permissions": [ "webNavigation","<all_urls>","tabs","webRequest","webRequestBlocking","storage" ], "background":{ "scripts":["background.js"] } }
在上面的 JSON 中,
manifest_version
应为 2,如 Google 文档所示。browser_action
指定扩展程序的图标和包含弹出窗口的 HTML 页面。permissions
定义授予扩展程序的权限集。在这种情况下,我们分配了访问 URL 和标签页的权限。我们还需要扩展程序能够跟踪和阻止请求,以及访问存储以保存被阻止的 URL。background
定义我们将一些 JavaScript 作为后台进程运行。Chrome 负责扩展程序系统,并将生成一个包含此脚本的页面。在这种情况下,我们不需要任何特定的 HTML。如果需要,也可以指定。
有关 Manifest 文件的更多详细信息,请在此处参阅 Google 的文档 here [^]。
HTML 页面和 CSS 文件
此扩展程序的 HTML 页面非常简单。它仅包含一个列表和几个按钮。弹出窗口的完整 HTML 如下所示
<!doctype html>
<html>
<head>
<title>BlockIt</title>
<link href="popup.css" rel="stylesheet" type="text/css">
<script src="popup.js"></script>
</head>
<body>
<div>
<p>Select the domains to block: </p>
<div>
<ul style="list-style: none;" id="hosts"></ul>
</div>
<div>
<button id="yes">Yes, block these domains</button>
<button id="no">No, changed my mind</button>
</div>
</div>
</body>
</html>
CSS 文件也只是对列表和按钮的最小样式设置。
JavaScript
这就是所有魔术发生的地方。如 Manifest 和 HTML 文件所示,这里有两个 JS 文件:background.js 和 popup.js。顾名思义,前者处理后台任务,后者处理扩展程序弹出窗口的代码。
background.js
后台脚本允许我们维护状态或编写长时间运行的进程。在这种情况下,我们需要跟踪所有标签页及其访问的 URL。因此,此脚本将需要变量来存储这些详细信息,以及一些事件处理程序来跟踪 Chrome 何时启动、何时打开或关闭标签页以及何时发出请求。使用 Chrome 的 API,我们可以按照以下格式将处理程序绑定到事件
chrome.<item>.<eventName>.addListener(<handler>,<filterAsJSON>,<moreInfoAsJSON>);
每个处理程序都必须具有特定的定义(参数的数量和类型),这些定义可以在文档中找到。例如,如果我们想在新标签页创建时触发一些代码,我们可以通过这种方式绑定处理程序(在大多数情况下,我使用了匿名函数。也可以使用具有正确定义的命名函数)
chrome.tabs.onCreated.addListener(function (tab){
// do something here
});
某些事件可以异步和同步处理,某些事件也可以返回数据。例如,onBeforeRequest
可以同步和异步处理。它还可以返回数据,指定对请求应采取的操作。下面的示例将阻止所有对 UglySite 的请求。它还指定了一个过滤器,该过滤器仅指示应将对 UglySite 和 VeryUglySite 的请求发送到扩展程序。
chrome.webRequest.onBeforeRequest.addListener(function(details){
return {cancel: true};
},
{urls:["*uglysite.com*","*veryuglysite.com*"]},
["blocking"]);
上面的代码将以同步方式阻止请求,而如果我们更改 blocking
为 asyncBlocking
,我们就可以异步执行此操作。在这种情况下,我们也可以指定一个回调函数。
除了监听事件外,我们还可以注册回调函数来监听从扩展程序发送的自定义消息。例如,当用户打开扩展程序弹出窗口时,我们需要获取当前标签页的所有请求。这可以通过以下方式实现
// In the background javascript
chrome.runtime.onMessage.addListener(function(request, sender, callback){
// request is an object that would look like this
// {
// action:'requests',
// tab: 1
// }
if(request.action = 'requests'){
callback(GetRequests(requests.tab));
}
});
function GetRequests(tabId){
// requestsMade and requestsBlocked are objects which would look like this if tabId was 1
// {'1':['url 1', 'url 2']}
return {"made": requestsMade[tabId.toString()], "blocked": requestsBlocked[tabId.toString()]};
}
在上面的示例中,我们使用 request.action
属性监听更多消息。下面的部分将展示如何将消息发送到此监听器。
对于此扩展程序,将处理以下事件
chrome.tabs.onCreated
:将当前标签页的属性添加到存储请求和已阻止请求的对象中。chrome.tabs.onRemoved
:将当前标签页的属性从存储请求和已阻止请求的对象中删除。chrome.webRequest.onBeforeRequest
:拦截所有发出的请求,并在需要时进行阻止。chrome.runtime.onMessage
:监听请求当前标签页所发请求的消息。这将使用requests
作为 action。chrome.runtime.onMessage
:监听告知后台进程已由用户更新已阻止 URL 列表的消息。这将使用resync
作为 action。
为了保存或获取数据,可以使用 chrome.storage.local
或 chrome.storage.sync
下的函数。两者都提供相似的函数和事件处理程序。两者的区别在于,local 只会将数据存储在当前计算机上。Sync 会在当前用户登录并启用同步的所有浏览器之间同步数据。如果用户未启用,sync 也将像 local 一样工作。
对于此扩展程序,我们使用 get 和 set 函数,这些函数允许我们读写 Chrome 存储中的数据。请注意,这些数据默认情况下未加密,因此不应存储敏感信息。以下代码片段显示了从存储中保存和检索数据。
// JSON data to save needs to be in key/value format
// set is used in popup.js
chrome.storage.sync.set(<jsonToSave>, <optionalCallback>);
chrome.storage.sync.get(['keyToGet'], function(result){
// Do something with result here
});
popup.js
此文件包含扩展程序弹出窗口所需的所有代码。它执行两个主要任务:加载时获取标签页发出的请求,以及单击保存按钮时将用户选择保存到存储。为了获取标签页发出的请求,它将 requests
消息发送到后台进程。以下代码用于发送消息
// call format. Not actual code
chrome.runtime.sendMessage(<requestJSON>,<callbackFunction>);
// actual code
chrome.runtime.sendMessage({action:'requests', tab: currentTabId},function(value){ GetRequests(value); });
在这里,为了获取当前标签页的 ID,使用了 Chrome API 的以下函数
// Here first JSON is used to filter the results and the function is the callback for the data returned.
chrome.tabs.query({active:true,currentWindow:true}, function(tabs){
// tabs array will contain one element with current tab
});
将所有内容整合在一起,这就是它的工作原理
虽然这看起来可能很复杂,但它是一段非常简单的代码,在这里被分解成非常小的部分。
将扩展程序添加到 Chrome
- 从上面的链接下载并解压代码。
- 在 Chrome 中,转到
chrome://extensions
页面,然后选中开发者模式
复选框。 - 单击
加载已解压的扩展程序
,然后选择包含下载代码的文件夹。 - 扩展程序现在应该显示在工具栏中。刷新页面以查看请求。
结论
本文的目的是提供有关编写 Chrome 扩展程序基础知识的思路。希望有所帮助。如需进一步阅读,请参阅 Google 的文档[^]。
历史
- 首次发布 - 2017 年 4 月 1 日