# chrome-plugin-v3-demo **Repository Path**: chunanyong/chrome-plugin-v3-demo ## Basic Information - **Project Name**: chrome-plugin-v3-demo - **Description**: 谷歌浏览器v3 demo 集合 很多地方存在瑕疵,多多交流多多改善。 对于这个本人也只是入门。 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2024-01-25 - **Last Updated**: 2024-01-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # chrome 插件 V3 学习文档 欢迎大家关注 前端浪客 ![](./img/weixin.png) ## 前言 相信很多前端人员都用过 Vue Devtools 调试 vue.js 工具的,这个工具用于调试 Vue.js 应用程序的 Chrome 和 Firefox DevTools 扩展。Chrome devtools 扩展用于调试 Vue.js 应用程序。 ![](./img/e9899f42-7f9f-471c-82d0-664276657a51.png) **插件是基于 Web 技术构建的,例如 HTML、JavaScript 和 CSS。它们在单独的沙盒执行环境中运行并与 Chrome 浏览器进行交互。** 插件允许我们通过使用 API 修改浏览器行为和访问 Web 内容来扩展和增强浏览器的功能。插件通过最终用户 UI 和开发人员 API 进行操作: 扩展用户界面,这为用户提供了一种一致的方式来管理他们的扩展。 扩展的 API 允许浏览器本身的扩展的代码访问功能:激活标签,修改网络请求等等。 要创建插件程序,我们需要组合构成插件程序的一些资源清单,例如 JS 文件和 HTML 文件、图像等。对于开发和测试,可以使用扩展开发者模式将这些“解压”加载到 Chrome 中。如果我们对自己开发出来的插件程序感到满意,就可以通过网上商店将其打包并分享给其他的用户。 ### 什么是 Chrome 插件 严格来讲,我们正在说的东西应该叫 Chrome 扩展(`Chrome Extension`),真正意义上的 Chrome 插件是更底层的浏览器功能扩展,可能需要对浏览器源码有一定掌握才有能力去开发。鉴于 Chrome 插件的叫法已经习惯,本文也采用这种叫法,但读者需深知本文所描述的` Chrome 插件`实际上指的是 `Chrome 扩展`。 Chrome 插件是为 chrome 浏览器添加功能的程序,可以获取网页内容并可以操作网页内容 ![](./img/1654674650036.jpg) ### Chrome 的插件(Plug-in)与扩展(Extension)的区别 "扩展"和"插件",其实都是软件组件的一种形式,Chrome 只不过是把两种类型的组件分别给与了专有名称,一个叫"扩展",另一个叫"插件"。 `插件(plugins)`一般是比较底层的应用,比如说 Flash、Java、Gears 等,每个插件都对应着相应的 dll 文件;而`扩展`则是一般的功能扩展。 - 扩展(Extension),指的是通过调用 Chrome 提供的 Chrome API 来扩展浏览器功能的一种组件,工作在浏览器层面,使用 HTML + Javascript 语言开发[*]。比如我们可能会用到的 Markdown viewer。 - 插件(Plug-in),指的是通过调用 Webkit 内核 NPAPI 来扩展内核功能的一种组件,工作在内核层面,理论上可以用任何一种生成本地二进制程序的语言开发,比如 C/C++、Delphi 等。比如 `Flash`插件、`PDF`插件等等,就属于这种类型。一般在网页中用 `` 或者 `` 标签声明的部分,就要靠插件来渲染。 你可以访问`chrome://plugins`查看已经安装的插件,访问`chrome://extensions/`管理安装的扩展程序。 ### 选择 chrome 插件而不是其他插件 1. 谷歌浏览器使用率高 2. 应用场景广,与 360、搜狗、QQ、百度等浏览器使用内核一致。同时浏览器插件的开发方式以及标准都是很类似的,能举一反三。 ### 使用方式 ![](./img/fc.jpg) ## 五个核心 ![](./img/mode.jpg) ### manifest.json > 每一个扩展、可安装的 WebApp、皮肤,都有一个 JSON 格式的 manifest 文件,叫 manifest.json,里面提供了重要的信息。 ```json // 基本 { "name": "chrome插件v3", // 姓名 "description": "当前是一个hello word 入门 demo", // 描述 "version": "0.0.1", // 版本 "manifest_version": 3, // manifest标准版本 比较成熟的是2,2023年将遗弃,统一使用v3 /** * @name 指定权限 * storage:可以使用 chrome 的文件系统来保存数据的 api * proxy: 可以使用对请求进行代理的 api; * declarativeNetRequest: 可以使用通过指定声明性规则来阻止或修改网络请求的 api; * options_ui:和 popup 类似,不过可以在tab页中打开,可以承载更多的内容,更方便配置; * devtools_page:开发者工具中的页面,比较常见的有Redux插件等; * chrome_url_overrides: tab页的内容,可以自定义; * contextMenus: 右键菜单 * tabs: 视窗 API * storage: chrome.storage API * .... */ "permissions": ["contextMenus", "tabs"], "omnibox": { "keyword": "chrome" }, // 选项卡功能 "action": { "default_popup": "/html/popup.html", // 使用一样的icon的话,可以不设置,默认使用icons图标 "default_icon": { "128": "/img/logo.png" } }, // 图标,一般偷懒全部用一个尺寸的也没问题 "icons": { "128": "/img/logo.png" }, // 会一直常驻的后台JS或后台页面 "background": { "service_worker": "scripts/background.js", "type": "module" // 支持模块化开发 } } ``` ```json // 主题颜色 { "theme": { "colors": { "frame": [71, 105, 91], "toolbar": [207, 221, 192], "ntp_text": [20, 40, 0], "ntp_link": [36, 70, 0], "ntp_section": [207, 221, 192], "button_background": [255, 255, 255] } } } ``` ```json // 内容执行的js { "content_scripts": [ { "matches": [""], "js": ["scripts/content-script.js"], "run_at": "document_end" } ] } ``` ```json // 选项 页面 { "options_page": "html/options.html" } ``` ```json // inject { "web_accessible_resources": [ { "matches": [""], "resources": ["js/inject.js"] } ] } ``` ### background 随着浏览器的打开而打开,随着浏览器的关闭而关闭,安装后会一直运行在浏览器中的程序。可以调用所有的 Chrome 扩展 API(除了 `devtools`),而且它可以无限制跨域,也就是可以跨域访问任何网站而无需要求对方设置 CORS。 配置: manifest.json ```json { "background": { // 没有前端页面,不支持dom。所有需要保持运行的脚本都要直接写在background.js里,同样他也不支持XMLHttpRequest,因此需要使用fetch来代替xhr请求。 "service_worker": "js/background.js", "type": "module" // 可使用module } } ``` js/background.js 各种全局需要的事件呀等等 ```js // 例子 --- 右键菜单 chrome.contextMenus.create({ id: "link-open", type: "normal", // 类型,可选:["normal", "checkbox", "radio", "separator"],默认 normal title: "新标签页打开链接", // 显示的文字,除非为“separator”类型否则此参数必需,如果类型为“selection”,可以使用%s显示选定的文本 contexts: ["link"], // 上下文环境,可选:["all", "page", "frame", "selection", "link", "editable", "image", "video", "audio"],默认page }); ``` > 注: 当前 js 不可操作 dom!!! ### content-script 向页面注入脚本的一种形式。(修改 dom) 配置: manifest.json ```json { "content_scripts": [ { "matches": [""], "js": ["js/content-script.js"], "run_at": "document_end" // "document_start"、"document_end"、"document_idle" } ] } ``` > 注:特别注意,如果没有主动指定 `run_at`(默认为 `document_idle`) content-script.js ```js alert("啦啦啦,我进来了"); ``` > 当前 js 不可操作 mv3 中的 api!!! ### popup `popup` 是点击 `browser_action` 或者 `page_action` 图标时打开的一个小窗口网页,焦点离开网页就立即关闭,一般用来做一些临时性的交互。例如为当前页面生成链接二维码。 配置: manifest.json ```json { "action": { "default_popup": "html/popup.html" } } ``` > 注:如果使用 `setPopup`方法的话,这里可不设置 html/popup.html ```html
hello world
``` ### inject 通过`content-script`中通过 DOM 方式向页面注入 js。 配置: manifest.json ```json { "web_accessible_resources": [ { "matches": [""], // 普通页面能够直接访问的插件资源列表,如果不设置是无法直接访问的 "resources": ["/js/inject.js"] } ] } ``` ## 六个展示 ![](./img/view.jpg) ### Actions(扩展程序图标) 浏览器的右上角增加一个图标,配置页面必须必须必须有一个 action 属性,,里面可以不写任何的东西,但是得有,要不后台 js 里面就不能使用 `chrome.action` 系列 api(会报错);安装后,默认情况下,这些会出现在扩展菜单(拼图)中。用户可以选择将您的扩展图标固定到工具栏。 manifest.json ```json // 这些值中的每一个都是可选的;技术上允许使用空字典。 { "action": { "default_icon": { // optional "16": "images/icon16.png", // optional "24": "images/icon24.png", // optional "32": "images/icon32.png" // optional }, "default_title": "点击我" // optional, shown in to } } ``` background.js ```js chrome.action.onClicked.addListener(function (tab) {}); ``` **API 说明** **disable** ```js chrome.action.disable( tabId?: number, callback?: function, ) ``` > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > callback: () => void **enable** ```js chrome.action.enable( tabId?: number, callback?: function, ) ``` > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > callback: () => void **onClicked** ```js chrome.action.onClicked.addListener( callback: function, ) ``` > callback: (tab: tabs.Tab) => void > 注: tabs.Tab 对应于 浏览器交互中的 tabs 属性描述 #### Popup **getPopup** > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > callback: (result: string) => void **setPopup** ```js chrome.action.setPopup( details: object, callback?: function, ) ``` > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > - `popup` (string): 要在弹出窗口中显示的 HTML 文件的相对路径。如果设置为空字符串 (''),则不显示弹出窗口。 > callback: () => void #### Icon path 方式: ![](<./img/1652709527(1).jpg>) ```js chrome.action.setIcon({ path: "/img/wer.png", }); ``` imageData 方式: ![](<./img/1652709681(1).jpg>) ```js const canvas = new OffscreenCanvas(16, 16); const context = canvas.getContext("2d"); context.clearRect(0, 0, 16, 16); context.fillStyle = "#00FF00"; // Green context.fillRect(0, 0, 16, 16); const imageData = context.getImageData(0, 0, 16, 16); chrome.action.setIcon({ imageData: imageData, }); ``` 图标是工具栏按钮中使用的主要图像。 ```js chrome.action.setIcon({ imageData: imageData }, () => { /* ... */ }); ``` > `action.setIcon()` API 旨在设置静态图像。它不应该用于模拟动画。 ```js chrome.action.setIcon( details: object, callback?: function, ) ``` **details** | 属性 | 类型 | 描述 | 例子 | | --------- | ---------------- | -------------------------------------------------- | -------------------------------------- | | imageData | ImageData/object | 要设置的图标 | -- | | path | string / object | 单元格 | '/img/wer.png' 或 {16:'/img/wer.png' } | | tabId | number | 将更改限制在选择特定选项卡时。选项卡关闭时自动重置 | -- | > callback:() => void #### Tooltip ![](./img/tooltip.jpg) ```json { "action": { "default_title": "点击我" } } ``` 当用户将鼠标悬停在工具栏中的扩展图标上时,会出现工具提示或标题。 ```js chrome.action.setTitle( details: object, callback?: function, ) ``` > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > - `title` (string): 鼠标悬停时动作应显示的字符串。 > callback: () => void #### Badge(标识) ![](./img/BadgeText.jpg) ```js chrome.action.onClicked.addListener(function (tab) { // 设置徽章文字 chrome.action.setBadgeText({ text: "我的", tabId: tab.id, }); // 设置背景颜色 chrome.action.setBadgeBackgroundColor( { color: [0, 0, 0, 1] }, //黑色 () => { /* ... */ } ); }); ``` 设置动作的标记文本。徽章显示在图标的顶部。 标识(badge)没有从清单(manifest)中获取的默认值。 **setBadgeText** ```js chrome.action.setBadgeText( details: object, callback?: function, ) ``` > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > - `text` (string): 可以传递任意数量的字符,但空间中只能容纳大约`四个字符` > callback: () => void **getBadgeText** > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > callback: (result: string) => void **setBadgeBackgroundColor** ```js chrome.action.setBadgeBackgroundColor( details: object, callback?: function, ) ``` > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > - `color` (string): [0,255] 范围内的四个整数组成的数组、 RGBA 颜色、16 进制。 > callback: () => void **getBadgeBackgroundColor** > details: > > - `tabId` (number): 将更改限制在选择特定选项卡时。选项卡关闭时自动重置。 > callback: (result: ColorArray) => void > 注:当设置了 default_popup 后,Icon、Tooltip、Badge 将失效。 ### ContextMenus(右键菜单) ![](./img/menu.png) `chrome.contextMenus` 模块用于在 Chrome 的右键菜单中增加自己的菜单项。 要使用 `contextMenus` API,必须在 manifest.json 中配置 contentMenus 权限(对应 icons 中的 16\*16 图标)。 ```json { "permissions": ["contextMenus"] } ``` **API 说明** 1. `ContextType`: ["all", "page", "frame", "selection", "link", "editable", "image", "video", "audio", "launcher", "browser_action", "page_action", "action"] 2. `ItemType`: ["normal", "checkbox", "radio", "separa"] **`chrome.contextMenus.create`** ```js chrome.contextMenus.create( createProperties: object, callback?: function, ) ``` > createProperties: > > - `checked` (boolean): 复选框或单选按钮的初始状态:选中时为 true,未选中时为 false。在给定的组中,一次只能选择一个单选按钮。 > - `contexts` (ContextType):此菜单项将出现的上下文列表。默认为 ['page'] > - `documentUrlPatterns`(string[]): 将项目限制为仅应用于 URL 与给定模式之一匹配的文档或框架。=====(Match Patterns) > - `enabled`(boolean): 此上下文菜单项是启用还是禁用。默认为 true。 > - `id`(string): 唯一 ID > - `parentId`(string | number) : 父菜单项的 ID > - `targetUrlPatterns`(string[] ): 类似于`documentUrlPatterns`,基于 img、audio、video 标签的 src 属性和 a 标签的 href 属性进行过滤。 > - `title`(string) : 要在项目中显示的文本 > - `type`(ItemType) : 菜单项的类型。 > - `visible`(boolean) : 该项目是否在菜单中可见。 > - `onclick`(function) : 单击菜单项时回调的函数。活动页面不可使用,应该使用`contextMenus.onClicked` 注册一个监听器。 > callback: () => void **`chrome.contextMenus.remove`** ```js chrome.contextMenus.remove( menuItemId: string | number, callback?: function, ) ``` > menuItemId (string | number): 要删除的上下文菜单项的 ID。 > callback: () => void **`chrome.contextMenus.removeAll`** ```js // 删除此扩展添加的所有上下文菜单项。 chrome.contextMenus.removeAll( callback?: function, ) ``` > callback:() => void **`chrome.contextMenus.update`** ```js // 更新先前创建的上下文菜单项。 chrome.contextMenus.update( id: string | number, updateProperties: object, callback?: function, ) ``` > id(string | number): 要更新的项目的 ID。 > updateProperties(object): > 与 `contextMenus.create` 的 `createProperties` 相同 > callback:() => void **`Events:onClicked`** ```js chrome.contextMenus.onClicked.addListener((info, tab) => {}); // info 当前点击数据 (checked、editable、frameId、frameUrl、linkUrl、mediaType、menuItemId、pageUrl、parentMenuItemId、selectionText、srcUrl、wasChecked) // tab 当前标签页面的对象数据 ``` ### Notifications(桌面通知) 通知用户发生了一些重要的事情。桌面通知会显示在浏览器窗口之外。 要使用 `Notifications` API,必须在 manifest.json 中配置 notifications 权限。 ```json { "permissions": ["notifications"] } ``` ```js chrome.notifications.create(null, { type: "basic", iconUrl: "/img/logo.png", title: "你好呀", message: "人生短短几十年,何不疯狂装疯癫!", }); ``` **API 说明** ### Omnibox(多功能框) ![](./img/omnibox.jpg) omnibox 应用程序界面允许向 Google Chrome 的地址栏注册一个关键字,地址栏也叫 omnibox。 当用户输入你的扩展关键字,用户开始与你的扩展交互。每个击键都会发送给你的扩展,扩展提供建议作为相应的响应。 要使用 `Omnibox` API,必须在 manifest.json 中配置 omnibox 关键字段 ```json { "omnibox": { "keyword": "chrome" } } ``` ### Options(选项页) 为了方便用户操作一个扩展功能(比如设置功能),可以弄一个选项页。(操作是浏览器头部右侧插件图标右键选择 选项) 要使用 `Options`,必须在 manifest.json 中配置 `options_page` 关键字段 ```json { "options_page": "html/options.html" } ``` ### overrides(覆写特定页) 使用替代页,可以将 Chrome 默认的一些特定页面替换掉,改为使用扩展提供的页面。这让扩展开发者可以开发更多有趣或者实用的基本功能页面。替代页通常会有大量的 CSS 和 JavaScript 代码。 扩展可以替代如下页面: - 书签管理器(`bookmarks`):从工具菜单上点击书签管理器时访问的页面,或者从地址栏直接输入 chrome://bookmarks。 - 历史记录(`history`):从工具菜单上点击历史记录时访问的页面,或者从地址栏直接输入 chrome://history。 - 新标签页(`newtab`):当创建新标签的时候访问的页面,或者从地址栏直接输入 chrome://newtab。 > 注: 一个扩展只能替代一个页面。 ```json { "chrome_url_overrides": { "newtab": "html/myPage.html" } } ``` ## 浏览器交互 ### Cookies 要使用 cookies API, 你必须在你的清单中声明"cookies"权限,以及任何你希望 cookie 可以访问的主机权限。 ```json { "permissions": ["cookies", "*://*.google.com"] } ``` **API 说明** ### devtools ### Events ### history ### management ### tabs ### windows ## 扩展实现 ### 消息传递 ### 国际化 ### 本地存储 ### 跨域请求 ### 打包与发布 ## 参考 **v2** [chrome 扩展开发中文教程](http://chrome.cenchy.com/samples.html) **v2** [chrome-plugin-demo](http://blog.haoji.me/chrome-plugin-develop.html) **v3** [chrome-api 中文文档](https://doc.yilijishu.info/chrome/)