Chrome插件开发【manifest.json】
目录
Manifest.json
常用结构
host_permissions
action
content_scripts
完整结构
options_ui
content_security_policy
homepage_url
minimum_chrome_version
incognito
web_accessible_resources
侧边栏(side_panel)
其它
Manifest.json
本文将会从“常用结构”和“完整结构”两部分切入,分别讲解。
常用结构
{"manifest_version":3,"name":"测试插件","version":"1.0","description":"实现了一个测试方法","icons":{"16":"icons/logo.png","48":"icons/logo.png","128":"icons/logo.png"},"action":{"default_popup":"popup/popup.html"},"background":{"service_worker":"background.js","type":"module"},"content_scripts":[{"matches":["<all_urls>"],"js":["content.js"],"run_at":"document_end"}],"permissions":["scripting", "tabs", "storage"],"host_permissions":["<all_urls>"]
}
- manifest_version[必填项]:manifest版本,必须是3(2已过期)
- name[必填项]:插件名字
- version[必填项]:插件版本,由您指定
- description:插件描述
- icon:插件图标
- action:浏览器动作(工具栏图标)
- permissions:权限声明
- host_permissions:主机权限
- content_scripts:内容脚本(注入到网页的脚本)
必填项(manifest_version、name、version)展现位置如下图所示:
浏览器动作(action)展现位置如下图所示:
host_permissions
作用
- 允许插件与指定网站交互:
- 访问网站的DOM
- 读取或修改网站内容
- 注入内容脚本(content-script)
- 启用特定API的网站访问权限:
- 使用chrome.cookies API访问指定网站的API
- chrome.webRequest AP监控指定网站的请求
- 跨域请求权限:
- 允许插件向指定网站发起跨域XMLHttpRequests或fetch请求
匹配语法
使用与内容脚本matches相同的模式语法
- “*”:匹配任意字符序列
- “?”:匹配任意单个字符
- “*://”:匹配所有协议(http、https等)
- “*.”:匹配所有子域名
- “/*”:匹配路径下的所有内容
示例
https://example.com/ // 只匹配example.com的HTTPS
*://example.com/* // 匹配所有协议的example.com
*://*.example.com/* // 匹配所有子域名
http://localhost/* // 匹配本地开发服务器
action
action可以在manifest.json文件里配置的参数只有两个:
- default_title:鼠标悬浮提示
- default_popup:点击插件显示的页面
content_scripts
{"content_scripts": [{"matches": ["https://*.example.com/*"],"exclude_matches": ["*://*/*admin*"],"css": ["content-styles.css"],"js": ["content-script.js"],"run_at": "document_idle","all_frames": false,"match_about_blank": false}]
}
- matches:脚本注入的URL
- exclude_matcher:排除不需要注入的URL
- css:注入的CSS文件数组
- js:注入的js文件数组
- run_at:控制脚本注入时机
- document_start:DOM加载前,CSS可用前
- document_end:DOM加载后,图片等资源未加载
- document_idle:DOMContentLaded事件后
- all_frames:控制注入位置
- true:注入到所有iframe
- false(默认):只注入到顶层框架
- match_about_blank:是否注入到about:blank页面(about:blank作为顶层页面不允许注入,在一个iframe里时允许注入)
注入的content-script是一个“半隔离”状态,具体如下:
特性 | 内容脚本 | 网页脚本 |
---|---|---|
DOM访问 | 完全访问 | 完全访问 |
JavaScript全局对象 | 隔离的副本 | 原始对象 |
变量/函数共享 | 不共享 | 不共享 |
扩展API访问 | 有限访问(chrome.runtime等) | 无访问 |
DOM是共享的:
// content-script.js
document.body.style.backgroundColor = "red"; // 会影响网页和其他内容脚本
JavaScript环境是隔离的:
// 网页脚本中
window.pageVar = "hello";// 内容脚本中
console.log(window.pageVar); // ❌ 输出 undefined(无法直接访问)
完整结构
{"manifest_version": 3,"name": "My Chrome Extension","version": "1.0.0","description": "A sample Chrome extension using Manifest V3","short_name": "My Extension","version_name": "1.0 Beta","icons": {"16": "icons/icon16.png","48": "icons/icon48.png","128": "icons/icon128.png"},"side_panel": {"default_path": "sidepanel.html","openPanelOnActionClick": true,"matches": ["<all_urls>"]},"action": {"default_icon": {"16": "icons/icon16.png","48": "icons/icon48.png"},"default_title": "My Extension","default_popup": "popup.html"},"background": {"service_worker": "background.js"},"content_scripts": [{"matches": ["<all_urls>"],"js": ["contentScript.js"],"css": ["contentStyle.css"],"run_at": "document_idle"}],"permissions": ["activeTab","storage","scripting","tabs"],"host_permissions": ["https://*/*","http://*/*"],"options_ui": {"page": "options.html","open_in_tab": false},"content_security_policy": {"extension_pages": "script-src 'self'; object-src 'self'"},"homepage_url": "https://example.com","minimum_chrome_version": "100.0","incognito": "spanning","web_accessible_resources": [{"resources": ["images/*.png", "styles/*.css"],"matches": ["<all_urls>"]}]
}
options_ui
options_ui是一个对象,包含以下常用属性:
- page(必须):指定选项页面的HTML文件路径
- op_in_tab(可选):布尔值,默认为false
- false:选项页面会嵌入在Chrome的“扩展程序详情”页面中
- true:选项页面会在新标签页打开
content_security_policy
用于限制插件可以加载和执行的资源,防止XSS等安全漏洞
- extension_pages:表示该策略适用于插件自身的页面(popup、options)
- script-src 'self':限制只能执行插件自身包内的脚本(不允许加载外部脚本,也不允许内联脚本)
- object-serc 'self':限制只能加载插件自身包内的插件资源(<embed>)
homepage_url
用于指定插件的官方首页URL
- 如不设置,默认指向该插件在Chrome应用商店的页面
- 当用户在扩展管理页面点击“查看详情”时,会跳转到此URL(若设置)
minimum_chrome_version
指定支持该插件的最低Chrome版本
- 若用户的Chrome版本低于此值,会在应用商店看到“不兼容”提示,且无法安装
- 版本号可以是主版本(100)或完整版本(100.0.4896.127)
incognito
定义插件在“无痕模式”下的三个行为,支持三个值:
- spanning(默认):插件在常规模式和无痕模式共享同一个实例,数据互通(chrome.storage等存储不会同步)
- split:插件在无痕模式中运行独立实例,与常规模式完全隔离,数据不互通
- not_allowd:禁止插件在无痕模式中运行
web_accessible_resources
指定插件内部的哪些资源文件可以被外部网页(或其它插件)访问
- resources:一个字符串数组,指定允许被外部访问的资源路径,支持通配符*匹配多个文件
- matches:一个字符串数组,指定哪些网页可以访问这些资源
侧边栏(side_panel)
侧边栏可以通过配置manifest文件实现
{"manifest_version": 3,"name": "我的侧边栏扩展","version": "1.0","icons":{"16": "icons/logo.png","48": "icons/logo.png","128": "icons/logo.png"},"background":{"service_worker": "background.js"},"side_panel": {"default_path": "sidepanel.html","openPanelOnActionClick": true},"action": {"default_title": "打开侧边栏"},"permissions": ["sidePanel"]
}
如需用户点击“插件图标”开关侧边栏,可以在background.js文件中添加如下代码:
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true }).catch((error) => console.error(error));
其它
更多Chrome插件开发学习,可以参考我的专栏:
Chrome插件_是洋洋a的博客-CSDN博客