阅读 285

Chrome扩展程序开发笔记-扩展与web页面的通信

可参考的资料

搜索到的资料可以作为参考,实际开发应以官方最新文档为准。

文件结构

  • manifest.json配置文件:必须详细说明文档
  • 其他JavaScriptHTMLCSS文件:根据功能和个人喜好,进行增减以及结构调整。

开发扩展程序与WEB开发类似,主要应用的技术为JavaScriptHTMLCSS等,再根据功能,调用chrome提供的各类API。

最终的文件结构可以类似这样:

my-extension
  - manifest.json  // required
  pages
    - background.html
    - popup.html
  icons
    - logo_16.png
    - logo_48.png
    - logo_128.png
  js
    - background.js
    - content.js
    - inject.js
    - popup.js
  css
    - popup.css
复制代码

开发时为防止后续功能繁多,我使用了Vue-Cli初始化项目,并使用插件vue-cli-plugin-chrome-ext修改文件结构,再根据自己需要修改vue.config.js以修改webpack的一些配置。

web页面与扩展程序之间通信

官方相关的文档

权限声明

首先,需要在manifest.json中,配置externally_connectable字段,来声明哪些web应用可以通过后面的方式,与扩展程序建立连接。在matches字段中,注明需要通信的web网站清单。

"externally_connectable": {
  "matches": ["*://*.example.com/*"]
}
复制代码

matches数组的每一项为URL字符串。且URL值必须要包含到二级域名级别。

externally_connectable字段,还可以声明ids字段,来指定需要通信的其他Chrome应用或者其他扩展程序。

通信方式

从Web页面向扩展程序发送消息,可以使用chrome.runtime.sendMessage,需要传入扩展程序的ID,回调函数可以接收Chrome扩展响应的消息:

const extensionId = 'deakpiepsidfpdfdioffidjfifjtest' // 想要与之通信的扩展ID

// 向Chrome扩展发送请求
chrome.runtime.sendMessage(extensionId, {
  event: 'requestEvent',
  data: requestData,
}, (response) => {
    console.log('res data', response)
}
复制代码

在Chrome扩展内使用chrome.runtime.onMessageExternal.addListener监听消息,接收后用sendResponse发送响应消息:

chrome.runtime.onMessageExternal.addListener(async (request, sender, sendResponse) => {
  if (request.event == 'requestEvent') {
    const res = 'res message'
    sendResponse(res)
  }
})

复制代码

监听和修改Web请求

文档位置:webRequest

依然是要先进行权限声明:

  {
      "name": "My extension",
      ...
      "permissions": [
        "webRequest",
        "*://*.google.com/"
      ],
      ...
  }
复制代码

Chrome提供了一系列的事件来监听Web请求生命周期的各个阶段,其中onBeforeSendHeaders事件被触发的阶段,可以用来增、删、改HTTP请求的headers。也可以在这个事件中取消请求。

用法, 修改之后return新的配置:

chrome.webRequest.onBeforeSendHeaders.addListener((details) => {
  const { requestHeaders } = details
  
  requestHeaders.push({
      name: 'x-request-xx',
      value: '...'
  })
  
  return { requestHeaders: requestHeaders }
})
复制代码

cookies操作

使用cookie相关的API,需要先在manifest.json中的permissions字段进行权限声明,要访问cookies的host也要一并声明:

{
  "name": "My extension",
  ...
  "permissions": [
    "cookies",
    "*://*.google.com/"
  ],
  ...
}
      
复制代码

Chrome共提供了5个方法和1个监听事件,用于cookie的操作和对cookie变化的监听:

方法

  • get: chrome.cookies.get(object details, function callback)
  • getAll
  • set
  • remove
  • getAllCookieStores

事件

  • onChanged

获取指定名称的cookie

chrome.cookies.get({
  url: 'https://example.com',
  name: 'token',
}, (cookie) => {
  console.log(‘token: ’, cookie.value) // cookie为获取到的cookie对象
})
复制代码

设置cookie

 chrome.cookies.set({
    url: 'http://example.com',
    name: 'x-request-xx',
    value: 'value...',
  }, (cookie) => {
    console.log('set cookie', cookie)
  })
复制代码

总结

Chrome扩展与web之间通信,还有一些其他方式,但个人认为按照官方文档中推荐的方式比较容易使用。

在实际开发时,如果担心扩展的id值发生变化,可以在background.js中利用chrome.runtime.id拿到当前扩展的id,通过content.js发送请求事件进行获取,最后可以以元素属性的值嵌入到HTML中,这样在WEB中就可以拿到啦~