前言:Chrome从2022年6月开始,新发布插件只接受V3版。2024年V2版已从应用商店下架。
浏览器扩展插件开发API文档
chrome官网(要翻墙): https://developer.chrome.com/docs/extensions/mv3
MDN中文:https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json
MDN英文:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json
搜狗扩展开发文档:API制定规范简介 - 《搜狗浏览器开发者文档》 - 书栈网 · BookStack
chrome扩展开发中文教程(manifest v2): chrome谷歌浏览器开发文档
360浏览器扩展开发教程(manifest v2): 开发文档
参考文章(感谢作者)
V2版天花板:【干货】Chrome插件(扩展)开发全攻略-好记的博客
V2-小茗同学: https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html
记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题_background.scripts' requires manifest version of 2-CSDN博客
chrome扩展(插件) V3版本使用_chrome插件v3中文手册-CSDN博客
Chrome 浏览器插件 Manifest.json V3 中权限(Permissions)字段解析_chrome插件permissions-CSDN博客
V3 版本 Manifest.json 文件全字段解析: https://zhuanlan.zhihu.com/p/678368901
两万+字数:从0到1带你开发 Chrome 浏览器 Manifest V3 版本插件-CSDN博客
Chrome扩展-相关API操作
- 侧边栏:chrome.devtools API
- 操作项:chrome.action API
- 菜单项:chrome.contextMenus API
- 显示桌面通知:chrome.notifications API
- 管理历史记录:chrome.history API
- 本地存储:chrome.storage API
- 控制标签页和窗口:chrome.tabs、chrome.tabGroups 和 chrome.windows 等 API
- 键盘快捷键:chrome.commands API
- 身份认证:chrome.identity API
- 管理插件:chrome.management API
- 提供建议:chrome.omnibox API
- 更新 Chrome 设置:chrome.proxy API
- 下载管理:chrome.downloads API
- 书签:chrome.bookmarks API
- 请求网络:chrome.webRequest API
Chrome扩展 控制网络
可以通过注入脚本、拦截网络请求以及使用 Web API
与网页进行交互,来控制和修改 Web
:
- 注入
JS
和CSS
文件 - 访问当前
Tab
页 - 控制
Web
请求 - 录音和屏幕截图
- 修改网站设置
manifest.json
manifest_version:从Chrome 18开始,开发者应该指定版本号为2;从2022年6月开始,新发布插件只接受V3版。
javascript
{
action(Manifest V3 及以上)
author
background
browser_action(仅 Manifest V2)
browser_specific_settings
chrome_settings_overrides
chrome_url_overrides
commands
content_scripts
content_security_policy
declarative_net_request
default_locale
description
developer
devtools_page
dictionaries
externally_connectable
homepage_url
host_permissions(Manifest V3 及以上)
icons
incognito
manifest_version
name
offline_enabled
omnibox
optional_permissions
options_page
options_ui
page_action(仅 Chrome 中的 Manifest V2)
permissions
protocol_handlers
short_name
sidebar_action
storage
theme
theme_experiment
user_scripts(仅 Manifest V2)
version
version_name
web_accessible_resources
}
javascript
{
//chrome插件的版本
"manifest_version": 3,
//插件名称
"name": "chrome浏览器扩展_名称",
//插件版本号
"version": "1.0.0",
//插件描述
"description": "一个简单的浏览器插件",
//默认语言(如果当前浏览器设置的语言不存在多语言配置文件,则默认中文),Chrome插件的多语言只能根据当前浏览器设置的语言来设定,无法通过代码更改语言
"default_locale": "zh_CN",
//内容安全政策,V2的value是字符串,V3是对象
"content_security_policy": {
//原文:此政策涵盖您的扩展程序中的页面,包括 html 文件和服务人员;具体不是很明白,但是参数值得是self,即当前自己
"extension_pages": "script-src 'self'; object-src 'self'",
//原文:此政策涵盖您的扩展程序使用的任何[沙盒扩展程序页面];具体不是很明白,但是参数值得是self,即当前自己
"sandbox": "sandbox allow-scripts; script-src 'self'; object-src 'self'"
},
//key,发布插件后会给一个key,把那个key的值放这里
"key": "xxx",
//icon,浏览器扩展程序管理里面的图标、浏览器右侧插件图标点开的下拉菜单展示的已开启插件的图标、以及插件详情页的标签卡的那个小图标
"icons": {
"16": "assets/img/rw_logo_16.png",
"32": "assets/img/rw_logo_32.png",
"48": "assets/img/rw_logo_48.png",
"128": "assets/img/rw_logo_128.png"
},
//背景页,后台脚本引入,v2是scripts:[xxx,xxx],可以引入多个js文件,
// v3是service_worker:'xxx',只能引入一个js,其他js文件可以在当前引入的js文件里面import引入
// 扩展程序管理界面的插件的那个"背景页"也将变成"Service Worker",改动之后background.js将和浏览器完全分离,即无法调用window和ducoment对象
//可以看介绍:
//1、//developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#background-service-workers;
//2、//developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/
"background": {
"service_worker": "js/background.js",
// 插件的后台脚本的类型,可以是 module 或者 script
"type": "module"
},
//注入脚本,值是个数组对象,可以有多个对象
"content_scripts": [
//每个对象代表一个注入的配置
{
//需要在指定页面注入的js脚本文件
"js": [
"js/content-script/jquery.min.js",
"js/content-script/content.js"
],
//需要注入js脚本文件的指定页面
"matches": [
"*://*.example.net/*",
"*://*.example.com/*",
"*://*.lagou.com/*"
],
//不允许注入js脚本文件的指定页面
"exclude_matches": ["https://*.xxx.com/*"],
//什么时候注入的js脚本,document_start=页面加载开始时,document_end=页面加载结束时
"run_at": "document_start"
}
],
//v2配置权限,在v2中的权限配置中,ChromeAPI权限和主机权限是一起配置的。v3是分开的
//ChromeAPI权限:需要使用Chrome的一些API的话需要配置对应的API权限,否则会报错未添加权限而无法使用,如tags标签页,contextMenus添加自定义右键菜单项)
// https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions
"permissions": [
"cookies", // 允许插件访问浏览器的 cookie
"contextMenus", // 自定义创建右键菜单API
"tabs", // 允许插件访问浏览器的 tab选项卡API
"storage", // 允许插件访问浏览器的 缓存API
"webRequest", // 监听浏览器请求API
...
],
// 主机权限:主机权限也可以称为请求白名单权限,在背景页backgroud.js里面或者popup页面调用某个网站请求时,增加该网站的白名单权限,如果没添加的则调用请求会报跨域)
"host_permissions": [
"https://*.example.net/*",
"https://*.example.com/*"
],
// 在浏览器插件图片上,右键会出现该插件名称,点击插件名称跳转的页面
"homepage_url": "https://www.example.com",
//动作API,原文:在 Manifest V2 中,有两种不同的 API 来实现操作: `"browser_action"` 和 `"page_action"` . 这些 API 在引入时扮演了不同的角色,但随着时间的推移它们变得多余,因此在 Manifest V3 中,我们将它们统一为单个 `"action"` API;
//v3配置,在v3中需要把browser_action废弃了,需要改成action,同时插件图标的点击监听事件也是一样,把chrome.browserAction改成chrome.action
//如果不添加action这个配置参数的话,chrome.action.onClicked.addListener()这个监听方法会无效
"action": {
"default_icon": { // 默认图标的文件路径
"16": "assets/img/rw_logo_16.png",
"32": "assets/img/rw_logo_32.png",
"48": "assets/img/rw_logo_48.png",
"128": "assets/img/rw_logo_128.png"
}
"default_title": "插件标题", // 默认是插件名称
"default_popup": "html/popup.html", // 弹出窗口的 HTML 文件路径
}
//通过网络访问的资源,对象中分了可外部访问的资源以及允许哪些外部网站可以访问该资源
"web_accessible_resources": [{
//允许访问的资源路径,数组传多个参数
"resources": ["assets/img/logo.png","assets/img/big.png",],
//允许访问资源的网站域名
"matches": [
"https://*.example.net/*",
"https://*.example.com/*"
]
}]
}
v2版本后台是叫背景页,上面配置里面添加的js文件都会在背景页里面引入加载进去,v2版本背景页中是可以调用window对象和document对象的(即可以引用jQuery.js之后使用$.ajax去发送请求)
v3版本后台是叫service worker 服务者,上面配置里面只能添加一个js文件,如果还需要引用其它js则只能在那个js文件里面用vue的import引入方式把其它文件引入加载,v3版本的service worker服务者中无法调用window和document对象(即无法引用jQuery.js,也就无法使用$.ajax发送请求了,因为jQuery是基于原生写的,里面有需要用到document对象),且原生的XMLHttpRequest请求也无法使用,以及vue的axios也是,想要调用请求需要用fetch()去进行请求
消息监听
javascript
// content_script.js
chrome.runtime.sendMessage({target: element, action: 'getJobInfo'},
function(response) {
console.log('收到后台发过来的职位信息',response);
}
);
// background.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.action=== 'getJobInfo') {
sendResponse({answer:`收到${msg.action}消息,马上传给你`,data:{}});
}
});