permissions 与 host_permissions
本教程共 56 篇 · 第 10 篇 · 更新于 2026-08-13 · 约 7 分钟阅读
本节目标:学完你能分清 permissions 和 host_permissions 两类声明式权限,知道常用权限名各自代表什么能力,并理解为什么 activeTab 比直接要 host_permissions 更可取。
扩展不是想干什么就干什么。浏览器出于安全考虑,要求扩展在清单里”先报备、再用权”。你声明了某个权限,代码里才能调用对应的 API;没声明就去调用,浏览器会直接报错。这一节讲清楚 Manifest V3 里两种最常被混淆的权限声明:permissions 和 host_permissions。
10-1 为什么要声明权限
想想一个密码管理器扩展:它需要读写你存过的账号,需要往当前网页的输入框里填内容,需要跨域把数据同步到服务器。这些动作如果随便一个网页脚本也能做,那就乱套了。所以浏览器把”能力”收口成权限,扩展必须在安装前就告诉用户”我要这些权限”,用户点头后才生效。
好处有两个:一是用户安装时能看到风险提示,决定是否信任;二是浏览器按最小可用原则收紧,没声明的接口一律不准用。Manifest V3 尤其强调”按需申请”,过度申请不仅难通过商店审核,还会吓跑用户。
权限写在清单顶层,是字符串数组。看一份完整示例:
{
"name": "Permissions Extension",
"version": "1.0",
"manifest_version": 3,
"permissions": [
"activeTab",
"contextMenus",
"storage"
],
"optional_permissions": [
"topSites"
],
"host_permissions": [
"https://www.developer.chrome.com/*"
],
"optional_host_permissions": [
"https://*/*",
"http://*/*"
]
}
这里出现了四个数组:permissions、optional_permissions、host_permissions、optional_host_permissions。前两个是 API 级权限,后两个是网站级宿主权限。下面拆开讲。
10-2 permissions 与 host_permissions 的根本区别
这是全节最关键点,我多说几句。
permissions 管的是”扩展能调用哪些浏览器 API”。比如 storage 让你用 chrome.storage 存数据,contextMenus 让你加右键菜单,alarms 让你设定时任务。它和”具体哪个网站”无关,是一种横向的能力开关。
host_permissions 管的是”扩展能访问哪些网址的内容”。比如你声明了 https://www.developer.chrome.com/*,扩展就能对该站发起跨域请求、读取其页面信息、在内容脚本里与之交互。它针对的是网站来源,是一种纵向的范围授权。
一句话区分:permissions 是”能做什么动作”,host_permissions 是”能在哪些网站上做”。 两者经常要配合使用——例如内容脚本要注入到某站并读取其 DOM,既要在 content_scripts.matches 里匹配该站,通常还要在 host_permissions 里声明该站(取决于具体 API)。
Note注意 host_permissions 和 content_scripts 的 matches 不是一回事。matches 决定”脚本注入哪些页面”,host_permissions 决定”扩展对该站拥有哪些跨域/读取能力”。前者是注入范围,后者是权限范围。
10-3 几个常用的 permissions 名称
下面列的是 MV3 里最常见、最该认识的 API 权限名。不是全部,但覆盖了绝大多数扩展会碰到的:
storage:读写 chrome.storage(本地/同步存储)。几乎每个扩展都用,且对用户无感、无警告,强烈建议。activeTab:用户主动触发时(比如点了工具栏按钮),临时获得当前标签页的访问权。详见 10-4。scripting:用 chrome.scripting 动态注入脚本或样式。配合 activeTab 或 host_permissions 使用。tabs:访问标签页的 url、title 等元数据。注意有 tabs 权限不代表能读页面内容,那归 host_permissions 和内容脚本管。bookmarks:增删改书签。cookies:读写 cookies。downloads:触发和管理下载。history:查询、删除浏览历史。notifications:弹出系统通知。contextMenus:添加右键菜单项。alarms:注册周期性或定时任务,替代 setInterval。declarativeNetRequest:MV3 中修改/拦截网络请求的唯一正规方式。sidePanel:控制侧边栏开关(配合清单的 side_panel 字段)。
Tip权限会触发安装时的警告横幅。比如要 history、要
<all_urls>宿主权限,用户会看到明显风险提示。能用 activeTab 代替宿主权限的场景,尽量用 activeTab,警告更少、用户更放心。
10-4 activeTab:最小权限的代表
activeTab 值得单独拎出来,因为它最能体现 MV3 的”最小权限”思想。
普通情况下,要操作某个标签页的页面(比如往里注入脚本改背景色),你得在 host_permissions 里声明该站,甚至 <all_urls>。这意味着扩展”随时”都能动这些页面。
activeTab 换了个思路:只有当用户主动与扩展交互时(点击工具栏按钮、执行命令、点右键菜单),扩展才在”当前这个标签页”临时获得访问权,且只限这一次动作。权限在用户导航离开当前页面、或关掉标签时收回;只是切到别的标签页再切回来,授权还在。
{
"name": "Page Redder",
"version": "2.0",
"manifest_version": 3,
"permissions": [
"activeTab",
"scripting"
],
"action": {
"default_title": "Make this page red"
}
}
配上后台脚本,用户一点按钮就把当前页染红:
function reddenPage() {
document.body.style.backgroundColor = 'red';
}
chrome.action.onClicked.addListener((tab) => {
if (!tab.url.includes('chrome://')) {
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: reddenPage
});
}
});
这样做的好处:扩展不需要任何宿主权限,安装时零警告,用户信任度高。能不用 host_permissions 的场景,优先用 activeTab。
10-5 host_permissions:网站级别的授权
当你确实需要”长期、自动”地访问某些网站时,才用 host_permissions。比如一个翻译扩展要在后台静默抓取目标网页内容,或一个比价扩展要读取电商页面。
{
"name": "My extension",
"manifest_version": 3,
"host_permissions": [
"https://api.example.com/*",
"https://*.shop.com/*"
]
}
host_permissions 的值同样是匹配模式(和 content_scripts 的 matches 语法一致),支持 https://*.example.com/*、<all_urls> 等写法。声明后,扩展对这些站点可以发起跨域 fetch、读取响应、在内容脚本中与之充分交互。
Warning我建议你把 host_permissions 收窄到真正需要的域名,别图省事写
<all_urls>。一来安装警告吓人,二来商店审核对”过度申请宿主权限”很敏感,三来这也是对用户数据的尊重。
10-6 optional_permissions 与 optional_host_permissions 简介
前面示例里还出现了 optional_permissions 和 optional_host_permissions。它们是”可选权限”,安装时不申请、不显示警告,等用户用到某功能时再通过代码 chrome.permissions.request() 弹窗询问。
这套机制适合”高级功能才需要”的权限。比如你的扩展基础功能只用 storage,但有个”显示热门网站”的进阶功能才需要 topSites,那就把 topSites 放进 optional_permissions,用户点开该功能时再申请。
这一节不展开 request 的写法(属于权限模型的后续章节),你只要知道它们的定位:主权限写 permissions/host_permissions,锦上添花、可能惹警告的权限写 optional 系列。
10-7 写一份权限声明清单
把这一节的内容收拢,一份”克制而清晰”的权限声明长这样:
{
"manifest_version": 3,
"name": "轻量划线笔记",
"version": "1.0.0",
"description": "在网页上划词做笔记,本地保存。",
"permissions": [
"storage",
"activeTab",
"scripting"
],
"host_permissions": [
"https://*.my-note-sync.com/*"
],
"content_scripts": [
{
"matches": ["https://*/*"],
"js": ["content-script.js"],
"run_at": "document_idle"
}
]
}
这份清单的原则很清楚:基础能力只拿 storage;操作页面靠 activeTab + scripting 临时授权,不申请全网宿主权限;只有真正要同步的域名才写进 host_permissions。权限声明这件事,少即是多。下一章我们回头扫一遍清单里其余几个常用字段——options_ui、side_panel、web_accessible_resources、content_security_policy、commands,把它们也纳入你的清单工具箱。