Chrome Extension开发须知
基本概念
Extension是由HTML、CSS、JavaScript和图片等其他资源文件组成的压缩包。它可以增强浏览器体验,实现个性化。
Files
Extension没有做目录的约定,但是它们需要已配置文件的形式写在manifest中。manifest.json
中描述了Extension的基本信息、使用能力和重要文件。
manifest.json
1 | { |
manifest_version
表明使用manifest的格式版本号,目前是整数2icons
推荐使用PNG格式browser_action
和page_action
类型二选一,前者用于所有页面,后者用于特定一些页面。background
可以指定在后台运行的脚本chrome
打头的三个配置可以定制浏览器本身的UI或行为commands
快捷键配置content_scripts
描述需要声明式插入的规则devtools_page
描述自定义的devtools选项卡externally_connectable
描述其他能够连接到该Extension的url规则omnibox
配置关键词当用户在地址栏输入特定字符时,变成与Extension交互permissions
显式声明Extension需要使用的权限
Extension中的文件路径类似HTML中,通常使用相对路径访问。在使用绝对路径时,需要使用chrome-extension://<extensionID>/<pathToFile>
风格的路径,可以使用chrome.runtime.getURL()
得到某资源的绝对路径。
browser_action
下面是一个browser_action的manifest样例。
1 | // browser action |
browser_action的UI可以包括icon、tooltip、badge、popup。
- icon,可以是图片文件或HTML5 canvas元素。后者可以动态创建,以提供更流畅的效果。
- tooltip,即配置文件中的title
- badge,用于描述Extension工作状态的徽章,最长4个字符,可以调用browserAction API动态修改内容或背景色
- popup,点击Extension按钮弹窗的窗口,可以包含任意HTML内容,可以在
default_popup
中定义,或调用API动态修改
browser_action有下面一些最佳实践:
- 在Extension作用于大多数页面时使用,在作用于少数页面时使用page_action
- 使用更多彩和重的图标,体现出和轻量级page_action的区别
- 不要模仿chrome内置图标,会造成误解
- 注意图标在不同主题背景色下的表现形态
- 不要使用动图,会引起用户焦虑
page_action
更轻量级。
1 | // page action |
UI上没有badge,其余和browser_action一致。另外,在非指定页面下,会有灰度展示。最佳实践同上。
架构
除了manifest描述项目结构外,需要另外一些组件组成完整的Extension功能。
- background script,Extension的事件handler,用于监听对于Extension来说重要的浏览器事件
- UI元素,有多种体现形式,如右键菜单,omnibox,点击按钮的弹出层等
- content scripts,用于和页面交互的js脚本。它可以传递消息给Extension的其他部分
- options page,用于配置Extension的页面
下面是一些详细介绍
background scripts
有效率的后台脚本应该由浏览器事件触发,执行命令之后卸载。这部分脚本在manifest的background
中声明。
1 | { |
在scripts
可以指定需要执行的多个后台脚本。persistent
需要指定为false。只有使用了chrome.webRequest
API的后台脚本才指定persistent为true。
使用上,
- 在Extension加载时,初始化一次性配置。
- 添加监听函数,一些监听函数还提供更多参数便于筛选事件。
- 在监听函数内,实现业务逻辑
- 在卸载前,执行持久化数据、释放请求等操作
content scripts
Content scripts运行在页面的执行环境下,通过DOM访问页面元素并和所在的Extension交互。它还可以调用Chrome APIs完成一些原生操作。Content scripts执行在和页面JS脚本相隔离的环境里,两者共享1个DOM。
Content scripts有两种执行方式,命令式插入或声明式插入。前者通过chrome.tabs.executeScript
实现,后者通过在manifest中声明实现在访问特定url时自动加载js文件:
1 | { |
Content scripts和页面脚本虽然是隔离开的,但共享一个DOM,可以通过window.postMessage
沟通和传递消息。
Chrome API
Extension使用特定的Chrome API在浏览器的环境下执行原生操作。API绝大多数都是异步的,这意味着如果想知道操作的结果,需要在回调函数中进行操作。Chrome的所有API都整合在Chrome这个namespace下,根据类型拆分成多个子模块,如chrome.runtime。
页面通信
由于content scripts运行在网页环境下,它通常需要和Extension本身进行通信。
- 一次性通信,content scripts端使用
chrome.runtime.sendMessage
,Extension端使用chrome.tabs.sendMessage
。接收侧一律使用chrome.runtime.onMessage.addListener
- 持久性连接,类似上面使用
chrome.runtime.connect
或tabs.connect
,详见文档 - 跨Extension通信,使用
chrome.onMessageExternal
或runtime.onConnectExternal
接收事件,发送事件可以使用上面的一次性通信或持久性连接的方式