MV3 架构与内容脚本通信

共 39 题
📑 题目列表 39 题
#
★★★

1. Manifest V3 host_permissions 与 optional_permissions/optional_host_permissions 按需申请的工程价值

在 Manifest V3 中,扩展声明 host_permissions 与 optional_permissions/optional_host_permissions 的区别是什么?按需申请机制的工程价值体现在哪里?

  • host_permissions 与 optional_host_permissions 的声明方式差异
  • 权限按需申请(on click/permission request)的用户体验与合规价值
  • 最小权限原则与 Chrome 商店审核策略

host_permissions 在安装时一次性全部授予,用户无感知;optional_host_permissions 则要求扩展在运行时通过 chrome.permissions.request() 主动向用户请求,且必须在用户手势(如点击)回调中触发。工程价值在于:一是符合最小权限原则,降低审核被拒风险;二是让用户在看到功能实际价值后再授权,减少"安装即被吓退"的流失;三是可以根据功能开关动态决定是否申请某些站点权限。在 MV3 中,Chrome 强烈推荐使用 optional 权限,因为普通 host_permissions 会触发"访问所有网站"的醒目警告。

按需授权本质上是在"功能可用性"与"用户信任"之间做权衡。工程上建议把对特定站的访问做成 optional,仅在用户明确触发该功能时申请,并在权限被拒绝时优雅降级。

#
★★★

2. Manifest V3 Service Worker 替换 background page(持久后台)

Manifest V3 为什么用 Service Worker 替换 MV2 的 background page?非持久化后台带来哪些工程挑战?

  • MV3 中 background.service_worker 替代 background.page
  • 事件驱动、非持久的生命周期模型
  • 状态丢失问题的处理(chrome.storage、IndexedDB、事件监听注册)

MV3 用类型为 "module" 的 Service Worker 替代 MV2 的常驻 background page。Service Worker 是非持久化的,会在空闲约 30 秒后被终止,只有事件(如 chrome.runtime.onMessage、chrome.alarms、chrome.tabs.onUpdated)触发时才被唤醒。这带来状态保活问题:内存中的变量、打开的 WebSocket 连接都会在终止时丢失,而且不能使用同步的 localStorage/DOM。工程上必须把所有持久状态存入 chrome.storage 或 IndexedDB,在事件回调中重建上下文,并注册好全局事件监听器(必须在顶层作用域注册,不能嵌套在回调里)。

Service Worker 生命周期是 MV3 最核心的变化。3.0 版本之后 Chrome 提供了 partially 保活机制,但仍不能依赖常驻内存。正确的做法是"事件驱动 + 存储持久化",把每次事件当作一次全新的冷启动来对待。

#
★★★

3. MV3 content_script 与 page context 的 MAIN world 注入与 ISOLATED 隔离的工程取舍

Manifest V3 中 content script 在 ISOLATED world 与 MAIN world 分别注入的差异是什么?两者各自的工程取舍如何?

  • ISOLATED world 与 MAIN world 的隔离模型
  • 页面脚本与扩展脚本的 DOM 共享与 JS 对象隔离
  • chrome.scripting.executeScript 的 world 参数与工程取舍

content script 默认运行在 ISOLATED world,与页面脚本共享同一个 DOM 但 JavaScript 对象相互隔离,因此页面脚本无法直接访问 content script 的变量,content script 也无法直接读取页面脚本定义的全局变量。MAIN world 注入则与页面脚本共享 JS 环境,可以访问或覆盖页面脚本的全局对象,常用于注入到页面上下文(如监控页面的 window 对象、与页面库交互)。工程取舍:ISOLATED 更安全、不易被页面反编译冲突,但若要读取页面变量或调用页面函数则需通过注入 script 或使用 MAIN world;MAIN world 虽能力更强,但会污染页面环境且更易被页面检测。Chrome 95+ 通过 chrome.scripting.executeScript 的 world 参数支持 MAIN world 注入。

核心取舍是"隔离安全"与"页面上下文能力"的权衡。默认用 ISOLATED,只有明确需要操作页面 JS 对象时才用 MAIN world,并用 DOM 事件、CustomEvent 或 window.postMessage 进行跨世界通信,避免直接暴露扩展 API。

#
★★★

4. Message Passing(chrome.runtime.sendMessage、chrome.tabs.sendMessage、chrome.runtime.connect 长连接)

扩展内不同上下文(content script、background/Service Worker、popup)之间通过哪些消息通道通信?它们各自适用什么场景?

  • chrome.runtime.sendMessage 与 onMessage 的一次性消息
  • chrome.tabs.sendMessage 定向到指定 tab 的 content script
  • chrome.runtime.connect 长连接(Port)与流式/多消息场景

一次性消息用 chrome.runtime.sendMessage(发送到扩展)与 chrome.tabs.sendMessage(发送到指定 tab 的 content script),配合 onMessage 监听;长连接用 chrome.runtime.connect / chrome.tabs.connect 建立 Port,通过 port.postMessage 双向流式收发,适合需要持续双向通信的场景(如实时更新、大量消息)。MV3 中所有消息都需在 onMessage 回调中调用 sendResponse 并返回 true(保持异步通道),否则会被视为同步返回。long-lived connection 在 MV3 中仍可用,但需注意 Service Worker 终止时连接会断开。

选择一次性消息还是长连接取决于通信频率与方向性。一次性消息简单、自动清理;长连接适合高频或需要服务器推送语义的场景。sendResponse 返回 true 是异步响应的关键,否则响应会丢失。

#
★★★

5. MV3 扩展的 Service Worker 与 offscreen document 的协作

MV3 中 Service Worker 无法使用哪些 Web API?offscreen document 如何弥补这些限制?

  • Service Worker 缺失的 DOM/音频/剪贴板等 API
  • chrome.offscreen.createDocument 的创建与生命周期
  • offscreen document 与 Service Worker 的消息协作

MV3 的 Service Worker 没有 DOM、window、document,也不能直接使用 Audio、Clipboard、Geolocation 等需要 DOM/window 上下文的 API。chrome.offscreen.createDocument 可以创建一个隐藏的 offscreen document,提供这些能力(如 DOM 解析、音频处理、剪贴板操作、读取某些页面数据)。扩展通过 chrome.runtime.sendMessage 在 Service Worker 与 offscreen document 之间通信,offscreen document 完成后应 close() 释放资源。

offscreen document 是 MV3 对 Service Worker 能力缺失的"补丁"机制。它本质上是一个受控的隐藏页面,仅授予最小必要能力(通过 reasons 声明),用于执行需要 DOM 的副作用操作,而不应滥用。

#
★★★

6. Permissions(permissions 数组)与 Host Permissions(host_permissions)

扩展 manifest 中 permissions 数组与 host_permissions 数组的区别是什么?各自包含哪些内容?

  • permissions 声明的 API 权限(如 storage、tabs)
  • host_permissions 声明的站点访问权限(match pattern)
  • 两类权限的警告与授予时机差异

permissions 数组声明的是扩展 API 权限(如 "storage"、"tabs"、"scripting"、"activeTab"、"contextMenus"、"notifications"),授权的是对 Chrome 内部 API 的访问能力;host_permissions 声明的是对哪些网站(通过 match patterns,如 "https://example.com/*"、全站 "all_urls")拥有访问权限,授权的是对指定 URL 网络请求与内容读取的能力。两者在安装时都会触发不同的权限警告,且都支持 optional 版本(optional_permissions、optional_host_permissions)以满足按需授权。二者在 MV3 中分离,host_permissions 不再能被 permissions 隐式覆盖。

区分这两类权限有助于设计最小权限清单:API 权限控制"能调用什么接口",Host 权限控制"能访问哪些网站"。把站点访问放到 host_permissions(尤其是 optional)可显著降低安装警告的冲击。

#
★★★

7. Firefox 对 MV3(declarativeNetRequest、service worker)的支持现状与差异及 polyfill 策略

Firefox 对 Manifest V3 的 declarativeNetRequest 与 Service Worker 支持如何?与 Chrome 存在哪些差异?跨浏览器扩展如何做 polyfill?

  • Firefox 对 MV3 的采用进度与差异
  • declarativeNetRequest 与 webRequest 的差异
  • webextension-polyfill 统一 browser/chrome 命名空间

Firefox 从 109 版本起默认支持 MV3,但实现与 Chrome 不完全一致:Firefox 的 MV3 仍支持持久化 background page(不强制 Service Worker),declarativeNetRequest 的规则字段与上限与 Chrome 略有差异,且 Firefox 对 webRequest 阻塞式 API 的支持更宽。跨浏览器开发常用 webextension-polyfill(如 Mozilla 的 webextension-polyfill)将 browser 风格 Promise API 统一,并在构建期根据目标浏览器生成不同 manifest。工程上应做特性检测(feature detection)而非假定 API 存在,并维护一份兼容矩阵。

跨浏览器兼容的核心是"能力检测 + 构建期 manifest 差异化 + polyfill 桥接"。由于 Chrome 与 Firefox 的 MV3 语义存在断层,不能假设同一份代码在所有浏览器行为一致,需在 CI 中针对多浏览器跑测试。

#
★★

8. MV3 扩展的 User Scripts API(独立权限申请)

什么是 User Scripts API?它与普通 content script 有何区别?需要什么权限?

  • chrome.userScripts API 与用户脚本管理
  • 独立于 content_scripts 的权限申请
  • 与用户脚本管理器的关系

chrome.userScripts API(Chrome 120+)允许扩展注册和管理运行在 MAIN world 的用户脚本,用于构建用户脚本管理器(如 Tampermonkey 类)或提供高级用户自定义能力。它需要 "userScripts" 权限,并且脚本列表存储在 chrome.storage 中,可在运行时动态注册/更新。与普通 content script 相比,userScripts 运行在 MAIN world、可注入任意代码、支持通过 manifest 的 user_scripts.APIs 白名单暴露有限的扩展 API,权限更高、风险也更高。

User Scripts API 面向的是"用户自定义代码执行"场景,权限模型更严格。工程上应仅在确需用户脚本能力时申请,并严格控制可暴露给脚本的 API 面,避免安全风险。

#
★★

9. Action API(toolbar popup)、Side Panel API(侧边栏面板)

chrome.action(工具栏图标与 popup)与 Side Panel API(侧边栏面板)分别用于什么场景?如何配置?

  • chrome.action 的 default_popup、badge、onClicked
  • chrome.sidePanel API 与 side_panel 面板
  • 两类 UI 的适用场景

chrome.action 提供工具栏图标、badge 文字、default_popup(点击图标弹出的界面)以及 onClicked 事件。Side Panel API(Chrome 114+)允许扩展在浏览器侧边栏显示常驻面板,适合需要持续展示、与主页面并排交互的工具(如 AI 助手、笔记、调试面板)。侧边栏通过 manifest 的 side_panel 字段声明默认路径,并在运行时用 chrome.sidePanel.open() 打开。二者可结合:popup 适合轻量临时操作,side panel 适合需要持续上下文的工作流。

选择 UI 形态取决于交互强度。临时性、点开即用的功能用 popup;需要长时间驻留、与主页面并行的功能用 side panel。side panel 还能借助 chrome.sidePanel.setOptions 按主机动态调整。

#
★★

10. Manifest V3 的 declarativeNetRequest 与 webRequest 阻塞式的对比

MV3 中 declarativeNetRequest(DNR)与 webRequest 阻塞式 API 的差异是什么?为什么 MV3 推荐 DNR?

  • DNR 声明式规则与 webRequest 命令式拦截的机制差异
  • DNR 的静态/动态/会话规则集与规则上限
  • MV3 移除 webRequest 阻塞式能力的动机

DNR 是声明式的:扩展在 manifest 或运行时声明规则集(静态 staticRules、动态 dynamicRules、会话 sessionRules),由浏览器内核高效匹配,无需扩展进程参与,因此启动快、不阻塞。webRequest 阻塞式 API 需要扩展在请求生命周期中同步处理,可能阻塞浏览器、泄露隐私,MV3 中已移除 onBeforeRequest 等阻塞式接口(部分保留给企业/受控扩展)。DNR 规则有数量上限(动态+会话规则合计约 5000 条,静态每规则集 100000 条),但足以覆盖拦截、重定向、修改请求头等常见需求。

DNR 把"拦截逻辑"下沉到浏览器内核,是一种性能与安全上的权衡。工程上应把广告拦截、请求改写等能力用 DNR 实现,避免依赖中断的 webRequest 阻塞 APIs。

#
★★

11. chrome.storage.local/sync/managed 在配额与跨设备同步的工程取舍

chrome.storage 的 local、sync、managed 三种存储有何区别?在配额与跨设备同步上如何取舍?

  • local(每设备、配额 10MB)与 sync(跨设备、配额 约 8KB/项)
  • managed(由企业策略或托管管理,只读)
  • 大数据与敏感数据的存储选择

chrome.storage.local 存储在本地设备,MV3 中默认配额约 10MB(可用 chrome.storage.local 的 QUOTA_BYTES 限制),适合大块数据、瞬时数据;chrome.storage.sync 通过用户同步账户跨设备同步,每项最大约 8KB、总配额约 100KB,适合设置、偏好等小数据;chrome.storage.managed 由企业策略(managed policy)或托管扩展提供只读配置,适合企业强制配置。工程取舍:跨设备一致的偏好用 sync,体积大或敏感的值用 local,同时注意 local 的配额限制与 sync 的字节限制,超出时需降级或分片。

存储选择的核心是"是否跨设备 + 数据大小 + 是否敏感"。敏感数据(如令牌)不应放 sync,应放 local 并加密;大块数据放 local 并管理配额。storage 的 API 是异步且有 Promise 形式,MV3 中 worker 可安全使用。

#
★★

12. native messaging 与本地进程通信的机制(Native Messaging Host manifest、stdio 协议)与适用场景

扩展如何通过 native messaging 与本地进程通信?Native Messaging Host manifest 与 stdio 协议是如何工作的?

  • chrome.runtime.connectNative 与 onConnectNative
  • Native Messaging Host manifest 的注册与路径
  • stdio 上的 JSON 消息协议(4 字节长度前缀)

native messaging 通过 chrome.runtime.connectNative 与本地可执行程序(Native Messaging Host)建立 stdio 上的 JSON 消息通道。Host 需要一个 manifest 文件(JSON),声明其路径、允许的扩展 ID 列表,并注册到系统注册表(Windows)或 ~/.mozilla/native-messaging-hosts(Linux/macOS)。消息格式为:4 字节小端长度前缀 + JSON 消息体。该方式适合需要与本地系统交互的场景(如文件系统访问、调用本地程序、读取硬件),但只支持与受信任的本地进程通信,且启动开销较大。

native messaging 是扩展与本地系统能力的桥,但安全边界严格——Host manifest 必须声明允许的扩展 ID,防止任意扩展调用。适合扩展无法直接访问的系统能力,但对性能敏感场景需谨慎。

#
★★

13. 扩展更新机制(update_url、更新检查间隔)与企业静默分发(策略强制安装、托管存储 managed storage)

扩展的自动更新机制如何工作?企业如何通过策略实现静默分发与托管配置?

  • update_url 自定义更新源与更新检查间隔
  • ExtensionInstallForcelist 策略强制安装
  • managed storage 托管配置

扩展默认从 Chrome Web Store 更新,Chrome 定时检查更新(通常每 5-6 小时一次,受 update_url 影响)。自定义 update_url 可指向自托管更新服务器,供私有/内网分发,但需维护 XML 更新清单。企业场景用 ExtensionInstallForcelist 策略强制安装(可绕过用户同意、静默安装),配合 ExtensionSettings 控制安装来源与权限,并通过 managed storage(chrome.storage.managed)下发只读配置。企业可让扩展读取策略配置实现"环境自适应"。

更新与分发是扩展运营的基础设施。公共商店分发简单但要遵守审核;企业自托管 update_url + 策略强制安装提供可控的灰度与合规,但需自建更新清单与签名机制。

#
★★

14. offscreen document 的适用场景边界(DOM 解析、音频处理、剪贴板)与单实例限制

offscreen document 适合哪些场景?有哪些能力限制与单实例约束?

  • offscreen 提供 DOM、音频、剪贴板等能力
  • 单实例限制(同一扩展仅一个 offscreen document)
  • reasons 声明与生命周期管理

offscreen document 用于 Service Worker 中缺失的 DOM 相关能力,典型场景:HTML/DOM 解析、音频处理(AudioContext)、剪贴板读写、读取页面截图数据、以及某些需要 window 的 API。关键限制是:同一扩展同时只能存在一个 offscreen document(单实例),且创建时必须声明 reasons 说明用途;它不能无限常驻,完成工作后应 close()。若需要多实例,需自行复用或串行处理。

offscreen document 是"受限的隐藏页面",应精确按需使用并尽快关闭。设计上要避免把 offscreen 当作常驻后台,而是作为一次性任务执行器。

#
★★

15. Content Scripts(content_scripts、隔离世界 ISOLATED)与页面脚本通信

content script 在 ISOLATED world 中如何与页面脚本通信?有哪些桥接方式?

  • content_scripts 声明与 ISOLATED world
  • window.postMessage / CustomEvent 桥接
  • 注入 script 到 MAIN world 的通信

content script 默认运行在 ISOLATED world,与页面脚本共享 DOM 但 JS 隔离。要与页面脚本通信,常用方式:通过 window.postMessage 或向 document 派发 CustomEvent(内容脚本与页面脚本都监听同一 DOM 事件来交换数据);或通过 chrome.scripting.executeScript 将功能脚本注入 MAIN world,再通过 DOM 事件桥接返回。注意:未注入的页面脚本无法直接调用 content script 的函数,需通过消息协议。

跨世界通信的核心是"以 DOM 事件为媒介"的异步协议。工程上应约定统一的 message 格式与事件名,避免直接暴露扩展 API 给页面脚本,降低安全风险。

#
★★

16. Chrome Extension 的 chrome.tabs API 在批量操作的应用

chrome.tabs API 在批量操作(如批量关闭、查询、静音)中有哪些应用模式?

  • chrome.tabs.query 批量查询标签
  • chrome.tabs.remove、update、discard 等批量操作
  • 批量操作中的权限与性能考虑

chrome.tabs.query 可按条件(url、windowId、active、audible 等)批量查询标签页,返回 tab 数组;配合 chrome.tabs.remove 批量关闭、chrome.tabs.update 批量更新(如置顶、静音、discard),chrome.tabs.discard 可释放内存。批量操作需注意:query 需要 "tabs" 权限或 host_permissions 才能读取 url/title 等敏感字段;大规模循环操作应分批、避免在 Service Worker 中阻塞。

chrome.tabs 适合做标签管理类工具(批量关闭、内存回收、分组)。关键是权限边界——读取 URL 需要 tabs 权限或 host 权限,且批量操作要控制频率与规模。

#
★★

17. 跨扩展通信(chrome.runtime.sendMessage、externally_connectable)

扩展之间如何通信?如何通过 externally_connectable 控制跨扩展/跨 Web 的通信边界?

  • chrome.runtime.sendMessage 发送给指定扩展
  • externally_connectable 声明允许通信的扩展 ID 与 Web 源
  • 来源验证的安全价值

扩展 A 可通过 chrome.runtime.sendMessage(extensionId, msg) 定向发送给扩展 B,B 在 chrome.runtime.onMessageExternal 中监听。为限制谁能与你通信,目标扩展需在 manifest 的 externally_connectable 中声明允许的扩展 ID 列表(matches)和允许的 Web 源(如 https://example.com)。这样可防止任意扩展或网页向你的扩展发送消息,是重要的安全边界机制。

externally_connectable 是"来源白名单"的落地,用于防止跨扩展/Web 的消息注入。工程上应严格限定允许的 ID 与源,避免使用通配的 allow 所有来源,尤其在处理敏感操作时。

#
★★

18. chrome.scripting.executeScript 在动态注入脚本的工程价值

chrome.scripting.executeScript 相比声明式 content_scripts 有什么优点?适用什么场景?

  • 运行时按需注入脚本(executeScript)
  • 注入函数/文件、指定 world、指定 tab
  • 与声明式 content_scripts 的取舍

chrome.scripting.executeScript(需要 "scripting" 权限)允许在运行时按需向指定 tab 注入脚本,支持注入函数(func)或文件(files),可指定 world(ISOLATED/MAIN)、执行时机。相比声明式 content_scripts(在 manifest 中静态声明、页面加载即注入),executeScript 更灵活:只在用户触发或条件满足时注入,减少不必要的注入开销与暴露面,且可在无 host_permissions 时配合 activeTab 临时授权使用。缺点是需要权限与运行时管理。

关键是"按需注入" vs "固定注入"。动态注入降低常驻暴露、更可控,适合需要交互后注入的功能;声明式适合页面一加载就需生效的轻量注入。activeTab + executeScript 组合是常见的最小权限模式。

#
★★

19. Chrome Extension 的 chrome.webRequest API 在 MV3 的迁移与限制

chrome.webRequest API 在 MV3 中受哪些限制?扩展应如何迁移?

  • MV3 移除 webRequest 阻塞式 API
  • 保留的可观察/非阻塞 API
  • 迁移到 declarativeNetRequest 的建议

MV3 中 webRequest 的阻塞式方法(onBeforeRequest 等在 callback 中同步修改/取消请求)被移除,仅保留非阻塞的观察能力(onBeforeRequest 可观察但不能阻塞修改,onCompleted 等可记录)。需要拦截/修改请求时应迁移到 declarativeNetRequest(DNR),后者声明式匹配、由内核执行。仅企业受控扩展(在 Chrome 中通过 policy 安装)仍可用部分阻塞式 webRequest。

webRequest 的阻塞式移除是 MV3 的核心"breaking change"。迁移路径是:拦截/改写用 DNR,数据观测用非阻塞 webRequest,两者结合覆盖绝大多数请求处理需求。

#
★★

20. Content Script 的 matches 与 exclude_matches 在范围控制的工程价值

content_scripts 的 matches 与 exclude_matches 如何控制注入范围?工程价值是什么?

  • matches 定义注入站点(match patterns)
  • exclude_matches 排除特定站点
  • 范围控制与性能、安全

content_scripts 使用 matches 声明要注入的站点(match patterns,如 "https://.example.com/"),exclude_matches 用于排除 matches 中不想注入的特定 URL(如 "https://example.com/private/*")。通过精确的范围控制,扩展只在必要站点注入脚本,减少资源占用、降低权限暴露面,并避免在无关页面触发不必要的行为。完善的模式还可用 js / css 分别声明注入资源。

范围控制是 content script 的最小暴露实践。越精确的 matches 越有利于安全与性能,也便于审核。应避免滥用 all_urls 而用最小必要模式。

#
★★

21. Chrome Extension 的 chrome.contextMenus 在右键菜单的工程应用

扩展如何通过 chrome.contextMenus 创建右键菜单项?在什么场景下适用?

  • chrome.contextMenus.create 与 contexts 类型
  • 菜单点击事件与信息传递
  • contextMenus 权限与 onInstalled 布局

chrome.contextMenus.create 可创建右键菜单项,contexts 指定菜单出现的上下文(如 "selection"、"link"、"page"、"image"),onClicked 事件处理点击。菜单项常添加在扩展自身的父菜单下(id 设为扩展 root),并在 onInstalled 中统一创建以避免重复。典型应用:对选中文本做翻译/搜索、对图片链接做下载、对页面元素做快捷操作。需 "contextMenus" 权限。

右键菜单是扩展的常见交互入口,适合"对当前选中内容/上下文执行操作"的场景。工程上要注意在 onInstalled 时创建菜单、避免重复创建,并处理好菜单项与 host 权限的匹配。

#
★★

22. Manifest V3 的 web_accessible_resources 在跨扩展共享的现代边界

MV3 中 web_accessible_resources 的配置有何变化?跨扩展共享资源的安全边界如何界定?

  • MV3 的 WAR 需按资源+匹配源声明
  • 由站点/扩展控制可访问性
  • 避免任意页面加载资源的风险

MV3 中 web_accessible_resources 需要在 resources 数组中明确每个资源(或通配符),并用 matches 指定允许访问该资源的来源(Web 源或扩展 ID),不再像 MV2 那样全局放行。这样做的价值是:只有白名单内的页面/扩展能加载你的资源,防止任意网页通过扩展资源 URL 进行跨域读取或利用。跨扩展共享资源时,通过 allowed extension IDs 精确声明。

MV3 的 WAR 是"资源最小暴露"的安全改进。工程上应把可访问资源限定到具体路径与来源,避免宽泛通配,防止资源被第三方页面滥用。

#
★★

23. Chrome Extension 的 chrome.notifications 在系统通知的工程实践

扩展如何通过 chrome.notifications 发送系统通知?有哪些工程实践?

  • chrome.notifications.create 与通知类型
  • notifications 权限与通知事件
  • 通知的聚合与生命周期管理

chrome.notifications.create 可创建系统级通知(basic/image/list/progress 等类型),需 "notifications" 权限。通知可设置按钮、点击回调(onClicked)、关闭事件(onClosed)。工程实践:通知应简洁、可点击跳转、及时清理(onClosed 释放引用)、避免高频通知打扰用户,并考虑与 chrome.storage 持久化用户偏好。

系统通知适合"后台发生事件需要提醒用户"的场景(如下载完成、任务完成、数据更新)。工程上要控制通知频次、提供开关并正确处理点击与关闭的生命周期。

#
★★

24. 扩展权限中 all_urls 与可选 Host Permissions 的工程取舍

声明 all_urls(所有站点)host permission 与使用可选 Host Permissions 的工程取舍是什么?

  • all_urls 的宽泛访问与安装警告
  • optional_host_permissions 按需申请
  • 全站点功能与最小权限的权衡

all_urls 授予对所有站点的访问权,安装时触发"读取和更改所有网站的数据"的强烈警告,用户信任成本高、审核风险大。optional_host_permissions 允许扩展在运行时按需向用户请求特定站点权限,减少安装时的警告冲击,符合最小权限原则。工程取舍:功能确实需要全站点访问且用户预期明确时用 all_urls;否则应优先 optional,把权限申请推迟到用户实际需要时(并处理拒绝后的降级)。

核心是"功能完整性"与"用户信任/合规"的平衡。大多数扩展可通过 optional_host_permissions + activeTab 覆盖绝大多数场景,all_urls 应作为最后手段。

#
★★

25. Chrome Permissions/Permissions-Policy 与扩展 CSP extension_pages 的工程价值

扩展页面的 CSP(content_security_policy)与 Permissions-Policy 有什么区别?扩展的 extension_pages CSP 如何配置?

  • extension_pages 的 CSP 与默认值
  • 禁止内联脚本与 eval
  • 与 Web 的 Permissions-Policy 概念区分

扩展页面的 CSP 通过 manifest 的 content_security_policy.extension_pages 配置,MV3 默认禁止远程代码、内联脚本和 eval,只允许扩展自身资源;这防止恶意代码注入扩展页面。Chrome 的 Permissions-Policy(HTTP 头 /

CSP 控制"扩展页面能加载什么脚本",Permissions-Policy 控制"Web 页面能委托哪些能力"。扩展的严格 CSP 是安全基线,远程代码(如从 CDN 加载脚本)会直接违反 MV3 规范。

#
★★

26. Chrome Web Store 审核政策与开发者控制台管理

Chrome Web Store 审核政策关注哪些方面?开发者如何管理发布与迭代?

  • 审核政策(最小权限、无远程代码、不欺骗)
  • 开发者控制台与发布流程
  • 版本管理、灰度、被拒处理

Chrome Web Store 审核关注:最小权限、无远程下载代码、不误导用户、隐私合规(数据收集声明)、内容安全等。开发者通过 Chrome Web Store Developer Dashboard 管理扩展、设置发布渠道(Public/Unlisted/Trusted Testers)、上传版本、查看统计与审核状态。被拒时需根据原因整改并重新提交。工程上应提前用自动化(如 manifest 校验、权限清单检查)降低被拒概率。

商店审核是扩展面向公众的合规门槛。工程上要多做自查:权限最小化、无 remote code、清晰的隐私政策、可靠的无法"欺骗"行为,避免反复被拒拖慢迭代。

#
★★

27. 扩展安全最佳实践(最小权限、CSP、来源验证)

扩展开发中有哪些安全最佳实践?如何从权限、CSP、来源验证等方面加固?

  • 最小权限原则
  • 严格 CSP 与禁止远程代码
  • 来源验证(externally_connectable、消息来源校验)

扩展安全最佳实践包括:只申请最小必要权限(用 optional/activeTab 减少全站警告);保持严格 CSP,禁止远程代码、eval、内联脚本;对来自 content script 或外部的消息做来源校验(校验 sender.id、使用 externally_connectable 白名单);避免把敏感信息(密钥)放在扩展代码里硬编码;及时清理 web_accessible_resources 暴露面;对用户输入做转义(防止注入)。

扩展运行在用户浏览器高权限上下文,是攻击面。核心是"最小暴露 + 严格边界 + 来源可信",每个层面都降低被利用的可能。

#
★★

28. DevTools Extension API(chrome.devtools.panels、chrome.devtools.network)

扩展如何通过 chrome.devtools API 扩展 DevTools?有哪些典型应用?

  • chrome.devtools.panels.create 创建面板
  • chrome.devtools.network 监听网络请求
  • chrome.devtools.inspectedWindow 访问被检查页面

扩展可通过 chrome.devtools.panels.create 创建自定义 DevTools 面板,通过 chrome.devtools.network.onRequestFinished 等监听网络请求,通过 chrome.devtools.inspectedWindow 访问被检查页面的信息(需谨慎)。典型应用:自定义调试面板、网络请求分析、性能分析、DOM/样式检查工具。注意:devtools 页面在 DevTools 打开时才有生命周期,且只能访问与 devtools 关联的上下文。

devtools API 让扩展变成开发者工具的一部分。工程上需注意 devtools 页面的生命周期(每次打开 DevTools 重新加载)与权限控制,避免对被检查页面做危险操作。

#
★★

29. OAuth2 PKCE 在 Chrome Identity API(chrome.identity.launchWebAuthFlow)

扩展如何通过 chrome.identity.launchWebAuthFlow 实现 OAuth2 PKCE 登录?相对隐式授权有什么优势?

  • chrome.identity.launchWebAuthFlow 的作用
  • PKCE(code + code_verifier)流程
  • 相比隐式授权(本地返回 token)的安全性

chrome.identity.launchWebAuthFlow 用浏览器弹窗完成 OAuth2 授权流程,适合走授权码(authorization code)+ PKCE 流程:扩展生成 code_verifier 与 code_challenge,authorize 请求携带 code_challenge,用户授权后回调返回 code,扩展用 code + code_verifier 换取 token。相比在 redirect_uri 中把 token 直接暴露给页面(隐式授权),PKCE 更安全,尤其适合无后端/原生客户端场景。扩展需在 manifest 声明 identity 权限与 OAuth 客户端 ID。

PKCE 解决"public client 无法保密 client secret"的问题。扩展把 code 换取 token 的请求可通过扩展自身或服务端完成,避免 token 出现在 URL 明文。工程上还要注意 token 的存储与刷新。

#
★★

30. webextension-polyfill 与 browser/chrome 命名空间差异及 Promise/callback 兼容层工程价值

webextension-polyfill 解决了什么问题?browser 与 chrome 命名空间在 API 形态上有何差异?

  • Chrome 的 callback 风格 vs Firefox 的 Promise 风格
  • webextension-polyfill 提供统一的 Promise API
  • 跨浏览器开发的工程价值

Chrome 的 chrome.* API 是 callback 风格,Firefox 的 browser.* API 是 Promise 风格。webextension-polyfill(Mozilla 官方)把 chrome.* 包装成 browser.* 的 Promise 风格,让开发者用统一 async/await 写法跨浏览器开发。工程价值:消除命名空间与 API 形态差异,减少样板代码,便于在 Chrome/Firefox/Edge 间复用同一套代码。使用时应配合 browser.runtime.sendMessage 等统一 API。

polyfill 的价值在于"一次编写、多端运行"。工程上还应做特性检测与构建期 manifest 差异化,形成完整的跨浏览器兼容策略。

#
★★

31. Enterprise 策略(ExtensionSettings/ExtensionInstallForcelist)对企业分发的作用与离线部署

企业如何通过 ExtensionSettings 与 ExtensionInstallForcelist 策略管理扩展?离线部署如何实现?

  • ExtensionInstallForcelist 强制安装
  • ExtensionSettings 细粒度控制(来源、权限、更新)
  • 离线部署与自托管 update_url

企业在 Chrome/Edge 的 Group Policy 中通过 ExtensionInstallForcelist 指定扩展 ID 与更新源 URL,实现强制、静默安装(用户无法卸载);ExtensionSettings 提供更细粒度策略:控制安装来源、允许的扩展、权限、更新 URL、甚至可以禁用某项能力。离线/内网部署用自托管 update_url(XML 更新清单)+ 内网 CRX 包,配合 ExtensionInstallForcelist 指定内网地址,实现无外网环境的分发。

企业策略让扩展在受控环境中按组织规范部署。工程上要支持读 managed storage 并按策略调整行为,使扩展能适配企业环境。

#
★★

32. 跨浏览器扩展的 manifest.json 差异与条件编译(build-time manifest 生成)的工程实践

跨浏览器扩展的 manifest.json 有哪些差异?如何用构建期 manifest 生成实现条件编译?

  • Chrome/Firefox/Edge 的 manifest 字段差异
  • 构建期通过脚本生成 manifest
  • 不同浏览器的最小字段集与版本兼容

不同浏览器对 manifest 的字段支持不同(如 Firefox 的 browser_specific_settings、browser_action 与 chrome 的 action 命名差异、Safari 的 extra 字段等)。工程上用构建脚本(如基于 webpack/rollup 的自定义 plugin 或 Node 脚本)在 build 阶段根据浏览器目标生成不同的 manifest.json,例如用模板 + 环境变量注入不同字段,实现"条件编译"。这样同一份源码可输出适配各浏览器的产物。

构建期 manifest 生成是跨浏览器工程的核心实践。它把"浏览器差异"收敛到构建配置层,避免运行时分支,同时便于后续自动迁移(如 MV2→MV3)。

#
★★

33. Manifest V3 替代 MV2 的关键变化

Manifest V3 相比 MV2 有哪些关键变化?对扩展开发有何影响?

  • background page → Service Worker
  • 移除 webRequest 阻塞式 → declarativeNetRequest
  • 远程代码/CSP 限制、WAR 最小暴露

MV3 相比 MV2 的关键变化:1) 用非持久化的 Service Worker 替代常驻 background page;2) 移除 webRequest 阻塞式 API,改用 declarativeNetRequest;3) 禁止远程代码,CSP 更严格,扩展页面只能加载本地资源;4) web_accessible_resources 改为按资源+来源匹配声明;5) 权限模型更严格,鼓励 optional 权限与 activeTab。这些变化提升了安全性与性能,但要求开发者重构后台逻辑为事件驱动、把拦截逻辑改为声明式。

MV3 是"安全与性能"导向的架构升级。理解其动机(减少常驻消耗、防远程代码、防跟踪)有助于在迁移时做出正确取舍。MV2 已逐步停止支持。

#
★★

34. MV3 Service Worker 非持久化带来的状态保活问题与 alarms、chrome.storage、事件驱动重建的替代方案

MV3 Service Worker 非持久化带来哪些状态保活问题?如何用 alarms、chrome.storage 与事件驱动重建来应对?

  • Service Worker 空闲终止导致状态丢失
  • chrome.alarms 周期性唤醒
  • chrome.storage 持久化与事件驱动重建

MV3 的 Service Worker 空闲约 30 秒即被终止,内存状态、WebSocket、定时器全部丢失。应对方案:1) 用 chrome.storage 持久化所有关键状态,事件唤醒后从 storage 重建;2) 用 chrome.alarms 周期性唤醒做定时任务(如轮询、清理),避免依赖内存定时器;3) 事件驱动设计——把逻辑放在各种事件回调(onMessage、onUpdated、onAlarm)中,事件到来即重建上下文;4) 避免在内存中保存长连接类状态。也可用 offscreen document 保活部分需要 DOM 的工作。

Service Worker 的"无常驻"是 MV3 的既定约束,工程上应把扩展设计成"无状态 + 存储持久化 + 事件驱动"的模型,把状态落盘到 storage。

#

35. MV3 web_accessible_resources 在内容脚本与页面间通信的工程价值

web_accessible_resources 在内容脚本与页面通信中发挥什么价值?如何安全使用?

  • 通过 WAR 暴露资源供页面脚本加载
  • 限定资源路径与匹配源
  • 页面脚本与内容脚本通信的桥接

页面脚本无法直接访问 content script 的 JS 对象,但可以加载 web_accessible_resources 暴露的资源(如图片、脚本)。工程上常用 WAR 暴露一个"桥接脚本"或资源,让页面脚本通过

WAR 是"页面脚本访问扩展资源"的受控入口。工程价值在于既提供跨世界通信的能力,又通过来源白名单收紧暴露面,安全与功能兼顾。

#

36. Options Page、Offscreen Document API

Options Page 与 Offscreen Document 分别用于什么?如何配置?

  • options_page/options_ui 配置设置页
  • offscreen document 提供 DOM 能力
  • 二者的工程用途

Options Page 通过 manifest 的 options_page(或 options_ui,支持 Chrome 原生样式)配置,用于向用户展示扩展的设置界面(如主题、功能开关),是用户调整扩展行为的主要入口。Offscreen Document 通过 chrome.offscreen.createDocument 在后台创建隐藏页面,用于执行需要 DOM/window 的能力(音频、剪贴板、DOM 解析)。二者区别:Options Page 面向用户交互,Offscreen Document 面向扩展内部的后台任务。

Options Page 是"用户设置的 UI",Offscreen Document 是"扩展内部的能力补充"。配置时区分清楚,Options 走 manifest,offscreen 走 API 运行时创建。

#

37. Manifest V3 的 content_security_policy 在脚本执行的现代应用

MV3 的 content_security_policy 如何约束扩展页面的脚本执行?有哪些现代应用?

  • extension_pages CSP 与默认策略
  • 禁止远程代码、eval、内联脚本
  • 扩展页面与现代前端框架的兼容

MV3 的 content_security_policy.extension_pages 定义扩展页面的 CSP,默认禁止远程代码、eval 与内联脚本('self' 之外一律不加载)。现代应用:确保扩展页面只加载本地打包的 JS,配合前端构建工具(如 webpack/vite 打包产物)将代码打包为本地文件;对需要动态脚本的场合用打包后的静态资源代替 eval。合理设置 CSP 可显著降低 XSS 风险。

严格 CSP 是 MV3 的安全基线。工程上应把一切脚本本地化打包,避免任何远程资源,同时认识并绕过旧式 Web 开发中依赖 eval/内联脚本的习惯。

#

38. chrome.declarativeNetRequest 规则上限与动态规则(updateSessionRules)

declarativeNetRequest 的规则上限是多少?如何用 updateSessionRules 管理动态/会话规则?

  • 静态/动态/会话规则集的数量上限
  • updateSessionRules 与 updateDynamicRules 的用法
  • 规则管理的最佳实践

DNR 的规则分布在三类规则集:静态规则(staticRules,manifest 中声明,每规则集上限 100000 条)、动态规则(dynamicRules,运行时用 updateDynamicRules 管理)与会话规则(sessionRules,用 updateSessionRules 管理,会话内有效)合计上限约 5000 条。updateSessionRules 接收 removeRuleIds 与 addRules 参数,用于运行时增删规则,适合需要根据用户操作实时调整拦截规则的场景。规则修改后浏览器内核生效,无需扩展进程常驻。

规则上限考验"规则资源管理"。工程上把稳定规则放静态、动态变更放 dynamic/session,并注意总数限制,及时清理不再使用的规则。

#

39. 扩展的 analytics 与 telemetry 在隐私合规(GDPR)下的工程边界与用户同意机制

扩展收集 analytics/telemetry 时在隐私合规(GDPR)下有哪些边界?如何实现用户同意机制?

  • 数据收集范围与最小化
  • GDPR 同意机制与隐私政策
  • 商店数据收集声明与合规

扩展收集遥测数据时需遵守 GDPR:数据收集最小化、明确告知用途、提供退出(opt-out)机制、获得用户同意(可做 opt-in 设置)、提供隐私政策。Chrome Web Store 也要求声明数据收集行为。工程上:把遥测做成默认关闭或明确 opt-in,用 chrome.storage 保存用户偏好,提供设置开关,并只在用户同意后发送匿名化数据;避免收集浏览历史等敏感信息。

遥测的合规边界是"最小化 + 明示 + 可控"。工程上把数据收集与同意机制内置为扩展功能,而非事后补救,才能在评审与合规上站得住脚。