首页 / 浏览器扩展开发入门教程 / 其他清单字段

浏览器扩展开发入门教程

其他清单字段

本教程共 56 篇 · 第 11 篇 · 更新于 2026-08-13 · 约 6 分钟阅读

清单manifestoptions_uiside_panelweb_accessible_resourcescommands

本节目标:学完你能认全清单里 options_ui、side_panel、web_accessible_resources、content_security_policy、commands 这五个常用字段,知道每个字段解决什么问题、基本写法是什么。

前面几章把核心字段拆得差不多了:基础字段、action、background、content_scripts、permissions。这一节做收尾,把剩下五个高频字段一口气过一遍。它们各自管一件事,单看都不复杂,但拼起来才是一个”完整可用”的扩展。

Note

本节是概览,每个字段只讲用途和最小写法。具体 API 怎么调(比如 side_panel.open()、commands 监听),留给后面的 UI 与 API 章节。

11-1 options_ui:选项页面

很多扩展需要让用户改设置:开关、阈值、账号绑定等。options_ui 就是声明”选项页”的入口。用户能在扩展管理页或右键菜单里打开它。

MV3 推荐用 options_ui(而不是老式的 options_page 单字段)。它接受一个对象:

{
  "manifest_version": 3,
  "name": "My extension",
  "options_ui": {
    "page": "options.html",
    "open_in_tab": false
  }
}
  • page:选项页的 HTML 文件,相对扩展根目录。
  • open_in_tab:可选,默认 false。false 时选项页嵌在浏览器风格的设置弹层里;true 时则在新标签页打开。

选项页本质就是一个普通 HTML 页面,里面写自己的脚本和样式,通常用 chrome.storage 把用户设置存起来,别的地方再读。声明之后,扩展管理页面上就会出现”选项”或”扩展程序选项”链接。

Tip

如果你只需要极简设置,open_in_tab 设 false 体验更轻。但当选项内容较多、需要大空间时,设 true 用整页更舒服。

11-2 side_panel:侧边栏

side_panel 让扩展拥有一个常驻浏览器侧边的面板,适合做”随时可见”的工具界面,比如 AI 助手、笔记栏、翻译窗。需要在权限里加 "sidePanel",并在清单声明默认页面:

{
  "manifest_version": 3,
  "name": "My extension",
  "permissions": ["sidePanel"],
  "side_panel": {
    "default_path": "sidepanel.html"
  }
}
  • default_path:侧边栏默认加载的 HTML 页面。
  • 还可以通过 action 的 default_title 等让用户在工具栏右键”展开边栏”来打开它。

侧边栏页面和普通网页一样写 HTML/CSS/JS,能用全部扩展 API。它和 popup 的区别是:popup 是点一下弹一下、用完即关,侧边栏则是持续停靠在窗口一侧。选哪个取决于你的交互形态。

Note

侧边栏的开关通常由用户控制(右键工具栏图标选择”显示侧边栏”)。清单里的 side_panel 只是设定默认页面,真正的打开/关闭逻辑在 API 章节讲。

11-3 web_accessible_resources:让网页能访问扩展资源

扩展包里有些资源(图片、字体、音频)需要被网页或内容脚本以 chrome-extension://<id>/... 的形式直接引用——比如内容脚本要把一张扩展里的图片插入页面 DOM,或 CSS 里要用扩展字体。默认情况下,网页读不到扩展内部文件,必须显式放行。

这就是 web_accessible_resources。MV3 里它从简单数组升级成了”对象数组”,每条声明”哪些资源、对哪些站点开放”:

{
  "manifest_version": 3,
  "name": "My extension",
  "web_accessible_resources": [
    {
      "resources": ["images/*.png", "fonts/*.woff"],
      "matches": ["https://example.com/*"]
    }
  ]
}
  • resources:要放行的资源,支持通配,如 images/*.png。
  • matches:哪些网站可以访问这些资源。尽量收窄,别写 <all_urls>,否则等于把扩展内部文件对全网开放。

代码里用 chrome.runtime.getURL("images/my_image.png") 拿到资源在扩展中的真实地址,再放进页面:

const url = chrome.runtime.getURL("images/my_image.png");
document.querySelector("img#logo").src = url;
Warning

web_accessible_resources 是”反向放行”——让外部网页能读到你的扩展文件。放行范围越大,潜在的信息暴露面越大。只放真正需要被网页引用的资源,能用内容脚本内部引用解决的就别放行。

11-4 content_security_policy:内容安全策略

CSP(内容安全策略)是扩展的安全护栏。MV3 下,扩展默认就有一条严格策略:script-src 'self'; object-src 'self';。它意味着:扩展自己的页面和脚本,只能加载来自扩展包内部的 JS,不能执行任何内联脚本,也不能从远程拉代码。

你可以自定义这条策略,但只能收紧、不能放宽到远程代码。常见场景是允许从本地开发服务器加载:

{
  "manifest_version": 3,
  "name": "My extension",
  "content_security_policy": {
    "extension_pages": "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:*; object-src 'self';"
  }
}
  • extension_pages:作用于扩展自身的页面(popup、options、side panel 等)。内容脚本不归这条策略管。
  • 注意 'self' 之外加上 localhost 仅用于本地开发调试,正式发布时通常不需要远程源。

有两条铁律务必记住:

  1. 内联脚本一律不行。<button onclick="..."> 这种写在 HTML 里的事件、<script> 块里直接写的代码,都不会执行。把所有 JS 抽到单独 .js 文件再引入。
  2. 远程代码一律禁止。不能从 CDN 加载 JS、不能用 eval 执行字符串。MV3 这条是硬性禁令,违反会被商店拒绝。
Tip

调试时若发现”脚本不执行”,先看控制台有没有 CSP 报错。最常见原因就是手滑写了内联 onclick。把逻辑移到独立 JS 文件就能解决。

11-5 commands:快捷键

commands 让扩展支持键盘快捷键,比如一键打开 popup、一键触发某功能。它还能用保留命令 _execute_action 直接把工具栏按钮绑定到快捷键,无需自己写监听:

{
  "manifest_version": 3,
  "name": "My extension",
  "commands": {
    "_execute_action": {
      "suggested_key": {
        "default": "Ctrl+Shift+Y",
        "mac": "Command+Shift+Y"
      },
      "description": "打开扩展弹出页"
    },
    "toggle-feature": {
      "suggested_key": {
        "default": "Ctrl+Shift+U",
        "mac": "Command+Shift+U"
      },
      "description": "切换某功能"
    }
  }
}
  • 键名是自定义字符串(如 toggle-feature),后台用 chrome.commands.onCommand 监听它。
  • suggested_key 的 default 是默认组合键,mac 可单独指定 Mac 上的键位。
  • _execute_action 是系统保留命令,作用是”按快捷键等于点了工具栏按钮”,省去自己接 onclick。
Note

快捷键可能被其他扩展或浏览器占用,suggested_key 只是”建议”,最终生效的键以浏览器分配为准。用户也能在快捷键设置页改。

11-6 小结与搭配建议

把这一节五个字段和前面学的合起来,一份”五脏俱全”的清单骨架就出来了:

{
  "manifest_version": 3,
  "name": "全能小工具",
  "version": "1.0.0",
  "description": "带选项页、侧边栏、快捷键的示例扩展。",
  "action": { "default_title": "小工具" },
  "background": { "service_worker": "background.js" },
  "options_ui": { "page": "options.html", "open_in_tab": false },
  "side_panel": { "default_path": "sidepanel.html" },
  "commands": {
    "_execute_action": {
      "suggested_key": { "default": "Ctrl+Shift+Y" },
      "description": "打开弹出页"
    }
  },
  "web_accessible_resources": [
    { "resources": ["images/*.png"], "matches": ["https://example.com/*"] }
  ],
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self';"
  },
  "permissions": ["storage", "activeTab", "sidePanel"]
}

回顾一下模块二(Manifest 清单详解)这六章:从基础字段、action、background,到 content_scripts、permissions,再到本节五个补充字段,你已经能把一份 Manifest V3 清单从头写到尾。接下来进入模块三,我们深入 background 背后的服务工作者(Service Worker)——它怎么被事件唤醒、生命周期有何特殊之处,以及那些新手必踩的坑。