chrome浏览器插件开发入门

1,007 阅读3分钟

官方文档:developer.chrome.com/docs/extens…

示例代码仓库:github.com/wyh-code/de…

什么是Chrome插件

严格来讲,我们正在说的东西应该叫Chrome扩展(Chrome Extension),真正意义上的Chrome插件是更底层的浏览器功能扩展,可能需要对浏览器源码有一定掌握才有能力去开发。鉴于Chrome插件的叫法已经习惯,本文也全部采用这种叫法,但读者需深知本文所描述的Chrome插件实际上指的是Chrome扩展。

一个 Chrome 扩展其实就是一个配置(入口)文件 manifest.json 和一系列 html、css、js、图片文件 等资源组成的一个.crx后缀的压缩包

核心概念

manifest:配置文件

文档:developer.chrome.com/docs/extens…

示例:demo-1

  • 插件没有严格的项目结构要求,只要有一个 manifest.json即可。
  • 用来配置所有和插件相关的配置,必不可少,必须放在根目录。
  • manifest_version、name、version 3个是必不可少的属性。

content_scripts:插件直接注入的文件

文档:developer.chrome.com/docs/extens…

示例:demo-2

  • 通过 content_scripts 属性,可以向页面插入一段 js脚本或者css。
  • 是一个数组,可以配置多项匹配规则,来达到个性化的定制。
  • 可以访问 chrome API,操作DOM,不能访问宿主页面js。

content-scripts不能访问绝大部分 chromeAPI,除了下面这4种:

  • chrome.extension(getURL , inIncognitoContext , lastError , onRequest , sendRequest)
  • chrome.i18n
  • chrome.runtime(connect , getManifest , getURL , id , onConnect , onMessage , sendMessage)
  • chrome.storage
{
  // 需要直接注入页面的JS
  "content_scripts": 
  [
    {
      //"matches": ["http://*/*", "https://*/*"],
      // "<all_urls>" 表示匹配所有地址
      "matches": ["<all_urls>"],
      // 多个JS按顺序注入
      "js": ["js/jquery-1.8.3.js", "js/content-script.js"],
      "css": ["css/custom.css"],
      // 代码注入的时间,可选值: "document_start", "document_end", or "document_idle",最后一个表示页面空闲时,默认document_idle
      "run_at": "document_start"
    }
  ],
}

inject_js:通过content_scripts注入的js

示例:demo-3

  • 可以和宿主页共享JS,但是不能访问chrome提供的api。
  • 使用postMessage发送消息给content_js,操作 chrome API。
  • 需要配置 web_accessible_resources。
{
 	// 普通页面能够直接访问的插件资源列表,如果不设置是无法直接访问的
 	"web_accessible_resources": [
		{
			"resources": ["./inject.js"],
			"matches": ["<all_urls>"]
		}
	]
}

background:后台常驻页面

示例:demo-4

  • 生命周期是插件中所有类型页面中最长的,它随着浏览器的打开而打开,随着浏览器的关闭而关闭。
  • 权限极高,几乎可以调用所有的Chrome扩展API(除了devtools),而且它可以无限制跨域。
{
  // 会一直常驻的后台JS或后台页面
  "background":
  {
    // 2种指定方式,如果指定JS,那么会自动生成一个背景页
    "page": "background.html"
    //"scripts": ["js/background.js"]
  },
	// 申请权限
  "host_permissions": ["<all_urls>"]
}

popup:点击图标展示的窗口

示例:demo-5

  • 自定义任何html。
  • 生命周期较短,焦点离开就会关闭。
  • 可引入js,内联js会报安全错误
"action": {
  "default_icon": {
    "16": "images/icon16.png",
      "32": "images/icon32.png"
  },
  "default_popup": "popup.html",
    "default_title": "HelloWorld"
}

options:选项页

示例:demo-6

  • 可引入js,内联js会报安全错误。
  • options_page 可新开一个页面。
  • options_ui 我为模态框形式。
"options_ui": {
    "page": "options.html"
},

"options_page": "options.html"

devtools:开发者工具

文档:developer.chrome.com/extensions/…

示例:demo-7

  • 自定义一个和多个和Elements、Console、Sources等同级别的面板。
  • 自定义侧边栏(sidebar),目前只能自定义Elements面板的侧边栏。
{
  // 只能指向一个HTML文件,不能是JS文件
  "devtools_page": "devtools.html"
}

权限对比

基础API

contextMenus

文档:developer.chrome.com/docs/extens…

示例: demo-8

  • 可以使用 chrome.contextMenus.create 来添加右键菜单。
  • chrome.contextMenus.onClicked.addListener 监听菜单点击。
const selectionOptions = {
  id: 'selection',
  title: '新建菜单 selection',
  contexts: ['selection'], // 菜单出现的上下文 selection:有选中项时出现
}; 
// 创建菜单
chrome.contextMenus.create(selectionOptions);

// 点击事件
chrome.contextMenus.onClicked.addListener((options) => {
  console.log(options, '==options=')
})

stroge

文档:developer.chrome.com/docs/extens…

示例:demo-9

对与程序来说,存储是至关重要的一个能力。有了存储能力,才有可能做一些复杂的应用交互。

  • 使用 chrome.storage.sync.set 来添加 storage。
  • 使用 chrome.storage.sync.get 来获取 storage。
  • 使用 chrome.storage.onChanged.addListener 来监听 storage 变化。
{
  "permissions":["storage"]
}

tab

文档:developer.chrome.com/docs/extens…

示例:demo-10

页签相关API

{
  "permissions":[ "tabs" ]
}

消息通信

文档:developer.chrome.com/docs/extens…

示例:demo-11