官方文档: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