关于javascript:Chrome-请求过滤扩展实现

1次阅读

共计 3908 个字符,预计需要花费 10 分钟才能阅读完成。

引子

接着 Chrome 扩大 : 入门,接下来开始实现一开始本人的想法:网络申请过滤。简略的说就是监听某个网站的所有申请,把想要的申请在扩大插件中展现进去。扩大名为 Capture Request。

  • Origin
  • My GitHub

需要具体化

下面的想法比拟含糊,为了达到这个目标,联合文档的示例,要做的有:

  1. 扩大要有对应的图标及提醒。
  2. 点击工具栏扩大图标,关上一个新的 Tab 页面,用来展现申请的相干信息。
  3. 扩大监听处于激活 Tab 的网站申请,能够配置过滤监听的网址。
  4. 对监听的申请,反对依据 url 筛选并导出。

有些性能不不便间接在文档找到,这个时候,倡议在 Chrome 商店找一个开源扩大,依据成果看外面用的一些 API,而后找到对应文档。这里参考了 FeHelper 外面的一些实现。须要留神到是 FeHelper 开发基于 manifest_version 版本为 2,以下开发扩大基于的版本是举荐的版本为 3,残缺代码见 Capture Request。

实现

图标相干信息配置

依照入门外面介绍的信息,图标可能呈现的中央有工具栏、扩大治理页、权限正告和 favicon 上,在 manifest.json 中配置的上面相干字段:

{
  "name": "Capture Request",
  "description": "Capture Request",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
    "default_icon": {
      "16": "xxx.png",
      "32": "xxx.png",
    }
  },
  "icons":{
    "16": "xxx.png",
    "32": "xxx.png",
  }
}

什么尺寸图标用在什么中央的具体阐明在这里,文档上举荐用 PNG 的图片格式。依照这个来,发现有的图标太小了会看起来显著含糊,也能够用比拟大的尺寸,Chrome 会本人把图片压缩到须要的尺寸。

点击扩大关上新 Tab 页面

在入门外面点击扩大的展示模式是关上了一个弹窗,在文档 Design the user interface 中介绍的模式有 Popup、Tooltip、Omnibox、Context menu、Override pages,最有可能就是 Override pages,但试了一下发现没有成果,于是去看他人的实现,发现能够通过监听点击图标事件关上新 Tab。

但看似能够间接用的 API,实际上还有上面几点要思考:

  1. 在哪里监听这事件?
  2. 什么时候监听这个事件?
  3. 怎么关上新 Tab ?
  4. 是否须要权限,如果须要,波及那些权限?

在入门外面增加性能是通过后盾脚本,文档结尾说的一句集体感觉很重要:

扩大是通过基于事件编程来扭转或加强 Chrome 浏览体验。

从文档中能够发现,在后盾脚本中能够解决下面提的第 1、2 两个问题,须要的权限是 scripting

关上 Tab 应用的 API 是 chrome.tabs,须要的权限是 tabs

次要做法是在 manifest.json 中增加上面配置:

{
  ...
+ "permissions": [
+   "scripting",
+   "tabs",
+ ],
+ "background": {
+   "service_worker": "background.js"
+ },
  ...
}

而后新建后盾脚本文件 background.js,并增加上面次要逻辑代码:

chrome.action.onClicked.addListener(() => {
  chrome.tabs.create({url: 'page.html'});
});

监听申请及配置

要把处于激活 Tab 网站上的申请显示到关上的扩大页面上,次要须要思考的点有:

  1. 怎么找到激活的 Tab?
  2. 怎么截获网页申请?
  3. 截获的申请怎么同步到扩大自定义页面上?

通过下面关上 Tab 的成果实现,能够联想到相干的 API 应该也在 chrome.tabs 中,发现提供了 query 办法能够解决第 1 个问题。

截获申请的办法通过网上搜寻,发现文档 chrome.webRequest,外面具体的介绍了扩大中申请的生命周期及触发的事件,通过比照思考,集体最初决定监听 onResponseStarted 事件,须要的权限是 webRequest。这样就解决了第 2 个问题。

参照入门外面扭转色彩的形式,相似的能够把申请缓存到 chrome.storage,而后在扩大页面获取,须要的权限是 storage。对于数据同步,能够通过监听 chrome.storage.onChanged 事件拿到变动的最新数据。这样就解决了第 3 个问题。

在调试的过程中,发现存在本地的数据应用 chrome.storage.sync 时,申请达到一定量后,会报错。看了文档发现这种形式的最大值有肯定的限度,不太适宜存储大量申请数据的场景,应用 chrome.storage.local 更加适合。

配置过滤申请的形式可间接依照入门外面的配置形式解决,但有一点须要留神的是,每当配置更新的时候,须要从新监听 onResponseStarted 事件。

次要做法是在 manifest.jsonpermissions 字段中增加 webRequeststorage

background.js 中增加次要代码:

// 贮存申请数据默认值
let requestList = []
// 网址过滤的默认值
let urlPattern = '<all_urls>'

// 监听申请事件的处理程序
const handlerResponseStarted = (details) => {
  // 找到处于激活状态的 Tab
  chrome.tabs.query({active: true}, (tab) => {requestList.unshift(details)
    chrome.storage.local.set({requestList});
    return {cancel: true};
  })
}

// 监听 storage 扭转事件
chrome.storage.onChanged.addListener((changeObj, areaName) => {const { urlPattern} = changeObj
  // 因为在 page.html 外面也监听了,所以要判断是不是 urlPattern 变动了
  if (areaName !== 'local' || !urlPattern) {console.warn('urlPattern does not change')
    return;
  }
  const {newValue} = urlPattern
  const hasAddListen = chrome.webRequest.onResponseStarted.hasListener(handlerResponseStarted)
  if (hasAddListen) {chrome.webRequest.onResponseStarted.removeListener(handlerResponseStarted);
  }
  chrome.webRequest.onResponseStarted.addListener(
    handlerResponseStarted,
    {urls: [newValue] },
  );
})

为扩大页面 page.html 增加脚本文件 pages.js,增加要害逻辑:

  chrome.storage.onChanged.addListener((changeObj, areaName) => {const { requestList} = changeObj
    // 因为在 background.js 外面也监听了,所以要判断是不是 requestList 变动了
    if (areaName !== 'local' || !requestList) {console.warn('requestList does not change')
      return;
    }
    const {newValue} = requestList || {newValue: [] }
    const newItem = newValue[0] || null
    if (!newItem) {console.warn('no data')
      return;
    }
    // 显示数据的逻辑
    showData(newItem)
  })

导出数据

截获了想要的数据,有须要导出到本地应用的场景,参考 FeHelper 外面的实现,找到了文档 chrome.downloads,须要的权限是 downloads

次要做法是在 manifest.jsonpermissions 字段中增加 downloads

pages.js 增加要害逻辑:

  let localFilterList = []; // 页面筛选后的数据
  // 点击导出的按钮
  const exportEle = document.querySelector('#operate-export')
  exportEle.addEventListener('click', () => {if (!localFilterList.length) {alert('无无效数据')
      return;
    }
    const txt = JSON.stringify(localFilterList)
    let blob = new Blob([txt], {type: 'application/octet-stream'});
    // 文件名称获取工夫的秒数,可依照本人爱好定义
    let dt = (new Date()).getSeconds();
    chrome.downloads.download({url: URL.createObjectURL(blob),
      saveAs: true,
      conflictAction: 'overwrite',
      filename: dt + '.json'
    });
  })

参考资料

  • Chrome 扩大 : 入门
  • Chrome 扩大 : 扩大是什么?
  • FeHelper Github
正文完
 0