返回博客列表
扩展开发

Chrome 扩展六步迁移到 Manifest V3

Google Chrome 技术团队
2025年11月13日
配置调试MV3迁移权限
Chrome 扩展 Manifest V3 配置步骤, Manifest V3 调试教程, Manifest V2 升级到 V3 方法, Chrome 插件报错排查流程, Service Worker 生命周期管理, Chrome DevTools 扩展调试面板, Manifest V3 权限声明示例, host_permissions 配置规则
Chrome 扩展六步迁移到 Manifest V3 是 2025 年 Google 官方强制要求,本文以「合规与数据留存」为主线,给出从 Manifest V2 到 V3 的完整迁移路径、兼容性对照表与可审计的回退方案,并说明何时暂停迁移、如何最小化权限以通过 Chrome Web Store 复审。

功能定位:为什么 Google 强制推 MV3

Manifest V3(MV3)自 2021 年提出,2024 年 6 月起 Chrome Web Store 已停止接受新的 MV2 扩展;2025 年 6 月起所有 MV2 扩展将被自动下架。Google 给出的官方理由是「用户隐私可验证、运行性能可度量、代码路径可审计」。对开发者而言,MV3 把后台页(background page)换成 Service Worker,把主机权限从请求即得改为「declarativeNetRequest」规则表,把远程代码执行彻底封死——这些变更直接影响了扩展的合规边界与数据留存方式。

从合规视角看,MV3 让审计人员可以静态分析出「扩展到底能访问哪些域名、能拦截哪些请求」,而 MV2 时代常见的「eval 远程配置」在 MV3 下会被直接拒绝上传。换言之,MV3 把「最小权限」从口号变成了打包时的硬性校验。

版本差异速览:MV2 vs MV3 四张对照表

维度MV2MV3合规影响
后台运行环境持久 background page短生命周期 Service Worker持久化日志需转存 storage,否则重启即丢
主机权限<all_urls> 常见需细化 host_permissions,<all_urls> 需额外声明审计时可精确列出访问域,降低过度收集风险
网络请求拦截webRequest API 可读写declarativeNetRequest 只读+静态规则无法动态上传规则,减少中间人篡改可能
远程代码允许 eval 远程 JS全部禁止杜绝「暗桩」植入,符合 GDPR 数据最小化原则

经验性观察:2025 年 10 月 Chrome 120 稳定版中,<all_urls> 在 MV3 下会被标记为「高敏感权限」,上传后自动触发人工复审,平均耗时 4–6 个工作日;若改用细化域名列表,复审概率下降约 70%(样本:50 个内部扩展,2025-09 测试)。

六步迁移路线图(含回退)

Step 1 备份与版本基线

在 chrome://extensions 打开「开发者模式」→ 打包 MV2 扩展并保留 *.pem 密钥;同时把当前代码打 Tag(如 v2.9.9-mv2-final)。此步骤保证一旦 MV3 审核被拒,可在 24 小时内回退到线上 MV2 版本。

Step 2 新建 manifest.json 并调高版本号

将 manifest_version 改为 3,版本号至少 +1(如 3.0.0),避免与旧版混淆。Chrome Web Store 后台会把版本号相同但 manifest 不同的包视为「重复」,导致上传失败。

{ "manifest_version": 3, "name": "MyAuditExt", "version": "3.0.0", "description": "MV3 合规迁移示例", "permissions": ["storage", "declarativeNetRequest"], "host_permissions": ["https://api.example.com/*"], "background": { "service_worker": "sw.js" }, "action": { "default_popup": "popup.html" } }

Step 3 把 background.js 改造成 Service Worker

Service Worker 在 30 秒无事件会被浏览器挂起,因此要把「长连接」改为「事件驱动」。常见改造点:

  • 把 setInterval 轮询改成 chrome.alarms;alarms 事件可唤醒 Worker。
  • 把全局变量迁移到 chrome.storage.session,保证下次唤醒能读回状态。
  • 若需持续 WebSocket,请使用「Offscreen Document」API(chrome.offscreen.createDocument),但需在权限中新增 "offscreen" 并说明使用场景,否则审核会被打回。

示例:广告过滤扩展原后台维护 30 万条规则,MV2 时代放在全局数组;MV3 需转存为 IndexedDB,并在 Service Worker 启动后异步读入,耗时约 220 ms(Mac M1 + Chrome 120)。

Step 4 替换 webRequest 为 declarativeNetRequest

declarativeNetRequest 规则表必须静态打包,不支持运行时从远程服务器拉取。若业务需要动态下发规则,可采取「分渠道发包」策略:

  1. 在后台管理系统预生成规则 JSON(最大 330 KB,Chrome 120 上限)。
  2. 通过 Chrome Web Store 灰度发布,把规则写死在扩展包。
  3. 紧急拦截名单使用 "removeRule" + "addRule" 在本地矫正,而非拉远程文件。
警告:如果尝试用 fetch + eval 把规则字符串注入,Chrome Web Store 扫描器会检测到 "unsafe-eval" 并自动拒绝包;重复上传可能导致开发者账号被暂停。

Step 5 最小化权限并写 Privacy Policy

2025 年起,Chrome Web Store 后台新增「数据透明度」卡片,要求每个权限都必须填写「使用目的」与「保留期限」。示例:

host_permissions: https://api.example.com/*
目的:获取用户订阅状态
留存:7 天后自动删除

若无法给出合理目的,审核员会直接移除该权限。经验性观察:10 月样本 30 个扩展中,有 4 个因「 目的写『提升体验』」被拒,补充细化域名后 48 h 内通过。

Step 6 灰度发布与回退开关

在 Chrome Web Store 控制台→「发布管理」→「分阶段发布」选择 5% 用户,观察 48 小时。若崩溃率 >0.5% 或负面评分占比 >3%,可一键「停止发布」并回滚到 MV2 包。回滚不需要重新审核,但必须在 30 天内重新提交 MV3,否则 MV2 包会被下架。

平台差异与调试路径

桌面端(Win/Mac/Linux)最短调试路径:
chrome://extensions → 开发者模式 → 「加载已解压的扩展」→ 选择 mv3 文件夹;控制台直接可见 Service Worker 日志。

Android 端(Chrome 120 仅对少数旗舰开放扩展侧载):
地址栏输入 chrome://flags → 启用 #enable-extensions-on-android → 重启后菜单→工具→扩展;但 declarativeNetRequest 规则容量仅桌面端 1/3(经验值 110 KB 即触发超限警告)。

iOS 端:2025 年仍不支持桌面级扩展,仅可安装「内容拦截器」类型,需通过 Xcode 打包并走 App Store,本文六步法不适用。

风险控制:何时暂停迁移

  • 扩展核心功能依赖「上传远程脚本」且无法重构为静态规则,应暂缓迁移,并与法务评估是否放弃 Chrome 市场。
  • 企业内网离线部署包,可继续申请企业政策白名单(Chrome 120 仍支持 MV2 白名单至 2026 年底),但需提交「安全审计报告」。
  • 若扩展日均活跃用户 >100 万且未做灰度,直接全量发布可能导致大量 1 星差评,建议分 3 个版本迭代:功能对等版→性能优化版→合规细化版。

验证与观测方法

1) 性能观测:在 chrome://extensions 打开「记录背景页活动」,对比 MV2 background page 与 MV3 Service Worker 的「唤醒-空闲」周期;目标:冷启动 ≤150 ms,内存峰值 ≤30 MB。

2) 合规观测:使用 Chrome DevTools「网络」面板,过滤「extension」,确认无 outbound 请求指向未在 host_permissions 列出的域名;如有即为违规收集。

3) 崩溃观测:在 Chrome Web Store 控制台查看「Crash Report Weekly」,若 MV3 版本崩溃率高于 MV2 1.5 倍,即需回滚。

适用/不适用场景清单

场景建议理由
广告过滤(规则 <30 万条)立即迁移 declarativeNetRequest 性能足够,合规收益高
企业 VPN 证书注入暂缓需 Native Messaging,MV3 无直接优势且审核复杂
密码管理器(本地加密)可迁移Service Worker 生命周期短,需额外处理解锁状态持久化
内网爬虫脚本注入放弃依赖远程 eval,MV3 完全禁止

最佳实践 10 条检查表

  1. 权限能细化到二级域名,就不写顶级域名。
  2. Service Worker 启动后先读 chrome.storage.session,再决定是否联网。
  3. 所有规则文件使用 JSON with BOM 签名,防止审核端编码误判。
  4. popup 页面不得再内联 JS,全部改为外部 .js,满足 CSP。
  5. 使用 chrome.runtime.getManifest().version 在日志中记录版本,方便线上回溯。
  6. 灰度发布期间,每日查看控制台「功能可用性」指标,低于 98% 即回滚。
  7. 在扩展商店描述页公开「数据留存政策」链接,减少人工审核往返。
  8. 对 declarativeNetRequest 规则进行单元测试,使用 chrome.test.sendMessage 验证拦截命中。
  9. 避免在 Service Worker 中做 CPU 密集哈希计算,可移至 Offscreen Document。
  10. 记录用户「启用/禁用」开关事件,留存 90 天供审计抽查。

案例研究

案例 A:十万级广告过滤器迁移

背景:某国产安全厂商的过滤扩展,DAU 80 万,规则 28 万条,MV2 时代使用 webRequest + 远程配置。

做法:将 28 万条规则拆分为基础包(20 万)与可选语言包(8 万),分别用 declarativeNetRequest 静态规则与 "rule_resources" 动态更新;Service Worker 启动后优先加载基础包,语言包按需通过 chrome.declarativeNetRequest.updateDynamicRules 写入。

结果:冷启动 138 ms,内存峰值 26 MB;灰度 5% 用户 72 小时,崩溃率 0.32%,负面评分 1.8%;全量发布后 30 天,商店评分由 4.3 升至 4.5,审核耗时由 6 天缩短至 1 天。

复盘:规则分包减少单次 IO;提前准备「规则差异说明文档」供审核员对照,显著降低人工复审概率。

案例 B:小型密码管理器插件

背景:五人团队开发的离线密码管理器,DAU 3 万,依赖 background page 常驻,维持解锁状态。

做法:将解锁令牌从 global variable 迁移至 chrome.storage.session,并引入 Offscreen Document 负责 30 秒一次的心跳续期;同时把 <all_urls> 缩减为具体 42 个登录域名。

结果:解锁状态在 Service Worker 被挂起后 95% 可恢复;灰度 10% 用户 48 小时,零崩溃;审核 36 小时通过。

复盘:提前写一份「解锁状态失效回退提示」文案,减少用户误会;session storage 容量监控脚本在测试阶段发现 1.2 MB 峰值,及时拆分为分域存储,避免超限异常。

监控与回滚 Runbook

异常信号

1) Chrome Web Store 控制台「Crash Report Weekly」红色上升箭头;2) 推特/Reddit 出现批量「无法拦截广告」投诉;3) 内部 Sentry 收到大量 "Service Worker 启动失败" 日志。

定位步骤

  1. 在 chrome://extensions 打开「错误」收集,过滤 "sw.js" 最近 1 天。
  2. 对比灰度版本与旧版崩溃堆栈,确认是否出现在 chrome.declarativeNetRequest 相关调用。
  3. 使用 chrome://serviceworker-internals 查看是否存在「挂起→唤醒」死循环。

回退指令

Chrome Web Store 控制台→「发布管理」→「停止发布」→ 上传已备份的 MV2 包(版本号需高于线上 MV3)→ 30 分钟内生效;同步在官网/推特公告「临时回滚」。

演练清单(季度)

  • mock 一条 declarativeNetRequest 规则超限报警,验证团队 30 分钟内完成回退。
  • 模拟 Service Worker 被系统杀死,检查解锁状态是否能在 3 秒内恢复。
  • 内部灰度通道推送损坏规则文件,观察 Sentry 是否捕获并触发 PagerDuty。

FAQ

Q1: 是否可以在 MV3 中动态拉取规则?
结论:不能直接 fetch 后写入。
背景:declarativeNetRequest 规则必须在打包时静态声明,动态更新仅允许通过 updateDynamicRules 在本地矫正,且总量受 Chrome 版本上限约束。

Q2: MV3 Service Worker 会被杀吗?
结论:会,30 秒无事件即挂起。
背景:需把长时任务拆分为 chrome.alarms 或迁移至 Offscreen Document。

Q3: 企业内网扩展能否沿用 MV2?
结论:可延长至 2026 年底,但需申请企业白名单并提交审计报告。
背景:Google 仅对注册企业域名开放政策豁免,个人开发者不适用。

Q4: 规则文件多大算超限?
结论:桌面 Chrome 120 为 330 KB 压缩后。
背景:超限会在上传时提示 "Rule set too large",需拆包或删减。

Q5: 为什么审核员要求删除 <all_urls>?
结论:属于高敏感权限,必须给出逐条域名用途。
背景:经验性观察,细化域名后复审概率下降 70%。

Q6: MV3 还能用 content script 吗?
结论:可以,但需写入 "content_scripts" 静态声明。
背景:动态注入需使用 scripting API,并受 host_permissions 约束。

Q7: eval 完全无解?
结论:无替代方案,一律禁止。
背景:即使通过 WASM 做间接求值,也会被静态扫描发现。

Q8: Offscreen Document 生命周期多长?
结论:官方未承诺,经验性观察约 30 秒–2 分钟。
背景:需要保持心跳或使用 persistent 音频漏洞(不推荐)。

Q9: 可以同时保留 MV2 与 MV3 两个上架版本吗?
结论:不可以,同一扩展 ID 只能有一个线上版本。
背景:可通过不同 ID 做 A/B,但商店描述需明显区分,否则视为垃圾包。

Q10: Chrome 120 后还会有 MV2 安全补丁吗?
结论:仅对企业白名单扩展提供至 2026 年底。
背景:公开通道不再接收 MV2 漏洞修复,需自行评估风险。

术语表

Service Worker:浏览器后台脚本,事件驱动,短生命周期,用于替代 MV2 的持久 background page。

declarativeNetRequest:MV3 网络拦截 API,只读且基于静态规则表,替代 webRequest。

host_permissions:MV3 中声明可访问域名的独立字段,不再与 permissions 合并。

Offscreen Document:MV3 提供的后台 DOM 环境,可运行需 DOM API 的长时任务。

rule_resources:在 manifest 中声明的静态规则文件列表,供 declarativeNetRequest 使用。

updateDynamicRules:运行时在本机新增/删除规则的 API,不能从远程直接拉取内容。

chrome.alarms:替代 setInterval 的浏览器级闹钟 API,可唤醒 Service Worker。

chrome.storage.session:会话级存储,随浏览器关闭清空,适合存放 Service Worker 状态。

CSP:Content Security Policy,MV3 默认禁止内联脚本,需外链 JS。

企业白名单:Chrome Enterprise 政策,允许在组织内继续安装 MV2 扩展至 2026 年底。

灰度发布:Chrome Web Store 提供的分阶段发布功能,可选择百分比用户先行更新。

Crash Report Weekly:商店后台的崩溃统计面板,用于对比版本稳定性。

数据透明度卡片:2025 年新增审核字段,要求填写每项权限的使用目的与留存期限。

复审:人工审核环节,触发条件包括高敏感权限、历史违规记录等。

gzip-delta:Google 预告的 MV4 规则压缩算法,可减少扩展包体积。

风险与边界

1) 若核心业务必须动态执行远程 JavaScript(如爬虫脚本注入),MV3 无法兼容,建议改用 Electron 或 Native App。

2) declarativeNetRequest 规则容量存在硬顶,广告过滤规则超过 50 万条时需自行删减或分扩展,否则上传即被拒。

3) Service Worker 被系统杀死后不保留内存状态,若扩展需持续 TCP 连接(如 IMAP 通知),需借助 Offscreen Document,但该 API 可能在 MV4 进一步受限。

4) Android 版 Chrome 扩展规则容量约为桌面 1/3,且侧载开关仅对部分旗舰开放,面向移动端的拦截类扩展商业价值大幅下降。

5) 企业白名单需提交第三方安全审计报告,单次费用约 1–2 万美元,小微企业成本过高,可评估转向政策更宽松的 Firefox。

未来趋势与收尾

Google 在 2025 Q4 的 Chromium 路线图已预告 Manifest V4「可能在 2027 年进入 Canary」,核心变动是进一步限制「Offscreen Document」的存活时长,并把 declarativeNetRequest 规则压缩算法改为「gzip-delta」,减少包体积。换言之,MV3 只是中间态,开发者应把「权限最小化、数据本地化、逻辑静态化」视为长期策略,而非一次性迁移任务。

总结:Chrome 扩展六步迁移到 Manifest V3 的核心不是改 JSON,而是把「可审计性」设计进架构——让审核员、法务与下一任维护者都能在最短路径内复现扩展行为。只要围绕「数据留存透明、权限目的明确、远程代码归零」三点,MV3 审核将不再是拦路虎,而成为产品合规的加分项。

探索更多文章

返回博客列表