65.9K
CodeProject 正在变化。 阅读更多。
Home

BlockIt - Chrome 扩展程序,用于阻止请求

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2017 年 4 月 3 日

CPOL

6分钟阅读

viewsIcon

15469

downloadIcon

367

阻止 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.jspopup.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"]);

上面的代码将以同步方式阻止请求,而如果我们更改 blockingasyncBlocking,我们就可以异步执行此操作。在这种情况下,我们也可以指定一个回调函数。

除了监听事件外,我们还可以注册回调函数来监听从扩展程序发送的自定义消息。例如,当用户打开扩展程序弹出窗口时,我们需要获取当前标签页的所有请求。这可以通过以下方式实现

// 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.localchrome.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

  1. 从上面的链接下载并解压代码。
  2. 在 Chrome 中,转到 chrome://extensions 页面,然后选中 开发者模式 复选框。
  3. 单击 加载已解压的扩展程序,然后选择包含下载代码的文件夹。 
  4. 扩展程序现在应该显示在工具栏中。刷新页面以查看请求。

结论

本文的目的是提供有关编写 Chrome 扩展程序基础知识的思路。希望有所帮助。如需进一步阅读,请参阅 Google 的文档[^]

历史

  • 首次发布 - 2017 年 4 月 1 日
© . All rights reserved.