Chrome 插件入驻实战:从 Manifest V3 到过审上架的完整路径

〇、写在前面:入驻到底难在哪

把代码写完只是第一步。Chrome 插件市场(Chrome Web Store)的上架动作,本质上不是一次文件上传,而是一份合规申报------你提交的不只是一个 zip 包,还有一整套权限声明、隐私披露与单一用途说明,审核团队会据此逐项核对。很多独立开发者花一个下午就能把扩展跑通,却要花一周在驳回与补材料之间来回。

本文的目标,是把这条从「能运行的扩展」到「商店里可安装」的路径一次讲清。内容大部分来自我把 Omni Suite 六款扩展(OmniPic、ResumeRadar、OmniGame、OmniPost、OmniSense、OmniVideo)搬上架的真实踩坑,以及 2026 年仍然有效的商店政策。读完你应当能避开八成以上的首次驳回。


一、准备开发者账号:一次性 5 美元与绕不开的前置项

第一步是注册开发者账号。进入 Chrome Web Store Developer Dashboard 后,你要先接受开发者协议并支付一次性 5 美元注册费 。这笔费用是按账号收取的,不按扩展个数重复计费,也不存在年费;它更像一道反垃圾门槛,而非营收来源。需要提醒的是,历史上该账号可容纳的扩展数量上限有过调整,提交前以开发者后台当页规则为准即可。

账号层面还有几个会卡后续发布的点,建议一次配齐:

  • 两步验证(2SV)是强制项。自 2021 年起,绑定发布能力的 Google 账号必须开启两步验证,否则连上传按钮都点不动。这不是可选项。
  • 验证联系邮箱。所有审核结果、驳回邮件、政策违规警告都发到这里,务必用一个你真的会看、且长期可控的邮箱。
  • 发布者显示名(Display Name)。它出现在你名下每个扩展下方,一旦确定后不易更改,用真名或公司名都比一个 Gmail 前缀更可信。
  • 经营者身份声明(Trader / Non-trader)。出于欧盟合规要求,商店现在要求开发者声明自己是经营者还是非经营者;若是经营者,必须公示联系信息,且会公开展示在商品页上。
  • 域名验证(可选但推荐)。把已验证的网站关联到发布者账号,可以在商品页拿到一个「已验证发布者」徽章,对转化率有帮助。

一个常被忽略的细节:用专属账号而非主力个人邮箱来发布。后续的所有权转移、团队协作(Group Publisher)都更省心,也避免个人账号风险牵连发布资产。

还有两个实务点值得提前排雷。其一,5 美元通过 Google 支付体系收取,准备一张能正常扣款的支付方式即可;但付费完成不等于立刻能发------账号的 2SV 与邮箱验证若未就绪,发布链路仍会被拦。其二是所有权转移本身可行却繁琐,所以不如一开始就选对账号形态。把「账号是否就绪」当成发布前的自检清单,先本地逐项核对,再谈上传,能省掉一轮邮件往返。


二、Manifest V3 是硬门槛:先把架构做对

2025 年之后,面向公众商店的新提交已不再接受 Manifest V2 。新扩展、老扩展的更新都必须落在 MV3 上,这是 2026 年最常被静默驳回的单一来源。把 manifest_version 写成 3 只是起点,真正的合规要深得多:

  • 后台从持久页面改为 Service Worker 。MV3 用 background.service_worker 取代了常驻的 background page。Worker 在空闲时会被终止,所以任何放在内存里的全局状态都会随休眠蒸发------状态必须改存 chrome.storage,定时器要换成 chrome.alarms,顶层事件监听要保持同步注册。
  • 网络拦截改走 declarativeNetRequest 。如果你过去依赖阻塞式 webRequest 去改写或拦截请求,在 MV3 里这条路不通,必须改造为声明式规则集(DNR 看不到请求体,规则资源需显式声明)。
  • 严格的 CSP 。MV3 默认禁止 unsafe-eval 与内联脚本,必须仔细检查 manifest 里的 content_security_policy 字段。
  • 禁止远程代码(Remotely Hosted Code) 。这是违反最频繁、后果最重的一条:不能在运行时从外部 URL 加载脚本、不能 eval 远程拉取的字符串、不能动态 import 远程模块。你可以和远程服务器通信(拉配置、同步数据、调 API),但不能把响应当代码执行------逻辑必须封在包里。

这里正好拿 OmniPic 举例。它的视觉计算依赖 TensorFlow.js 与 MobileNetV1,但模型权重是 vendored 进扩展包内 离线运行的,CDN(modelscope / hf-mirror / jsdelivr)只是「可镜像」的来源,推理时并不去远程拉可执行代码。这种「重活进 worker、模型随包走、绝不执行远程代码」的架构,正是 MV3 审核最欢迎的形态。OmniSense 把大模型塞进 Offscreen 的 WASM worker,同样遵循同一原则------连 Service Worker 里禁止使用动态 import() 这种规范限制,都被诚实写进了源码注释,而不是靠远程加载绕开。

如果你们是从 MV2 迁上来,迁移顺序有套路可循:先把 manifest_version 翻到 3 并把后台改成 service_worker 字符串,再把所有事件监听提到顶层同步注册;接着用 chrome.alarms 替换 setInterval/setTimeout 这类定时器(它们撑不过 Worker 休眠);然后用 chrome.scripting.executeScript 的新签名替换旧的 tabs.executeScript,并补上 scripting 权限;最后才把阻塞式 webRequest 规则改写成 declarativeNetRequest 规则集。按这个顺序走,比一次性大改更容易通过自测,也更容易在审核时解释清楚每一处变更。


三、权限最小化:每一个 permission 都要在代码里找得到

权限是审核最 meticulous 的一环。你 permissions 与 host_permissions 数组里的每一项,都必须在代码里有可验证的、真实被调用的用例。几个实操原则:

  • 删掉任何没被用到的权限。哪怕多一个声明了却没调用的权限,都可能直接触发「请求的权限未在代码中使用」的驳回。
  • 用具体域名取代通配 。能用 https://api.myservice.com/* 就不要写 <all_urls>。后台会对通配 host 明确提示「可能会导致深度审核、拖慢上架」。
  • activeTab 优先于 tabs 。如果你只在用户点击时访问当前页面,用 activeTab 比申请 tabs 权限更窄、更不易被盯上。
  • 运行时按需申请 optional_permissions 。非核心能力放到 optional_permissions,用到那一刻再弹窗请求。

有一类权限几乎必然引来人工审核:tabs、cookies、history、downloads、webRequest、debugger,以及任何宽泛的 host 模式。申请的底线是「每一个权限你都乐意向陌生人解释清楚它为什么必要」。与其在驳回后费力写理由去争辩,不如一开始就把清单 trim 干净------审核团队的判断口径是「权限与可见功能的匹配度」,多余权限本身就是减分项。


四、单一用途原则:一个扩展只做一件事

Chrome 要求每个扩展都有「一个狭窄且易于理解的单一用途」。这条规则有真实约束力,不是摆设。它的含义很具体:你的扩展应该为一个用户需求做一件事,不是两件,也不是「相关功能打包」。

判断标准其实朴素:

  • 过关的例子:一个帮你整理打开标签的标签管理器;一个在文本框里做语法检查的插件;一个给特定网站切暗色的开关。
  • 被拒的例子:一个「效率套件」同时拦截分心网站、统计时长、又给每个页面注入自定义 CSS------三件彼此独立的事堆在一起。

Omni Suite 处理这件事的方式值得参考:我们没有把图片、简历、游戏、发布、AI 助手、视频下载揉进一个巨型扩展,而是拆成六款独立产品,各自只有一个核心职责。这样做表面上是「发布六个而不是一个」,实际上反而让每一款的单一用途声明更干净、审核更顺。如果你的点子天然包含多个不相干功能,正确做法通常是拆成多个扩展,而不是赌审核员手软。


五、打包这件小事:ZIP 根目录必须有 manifest.json

上传物是一个单独的 ZIP 压缩包,两条规则覆盖了绝大多数首次打包失败:

  • 规则一:manifest.json 必须在压缩包根目录,不能套一层文件夹。把整个项目目录压缩、而不是压缩目录里的内容,是最常见的错误------如果你解压后看到的是「一个文件夹、manifest 在里面」,上传会被立即拒绝。正确做法是从扩展构建产物目录内部打包,让 manifest 直接位于顶层。
  • 规则二:只发会运行的东西 。排除 node_modules、源码映射(source map)、测试桩、.git、草稿 README、设计源文件等一切会膨胀包体的内容。审核员会看包里有什么,解释不清的文件只会招来追问。

在 macOS 上建议用命令行 zip 而非 Finder 的「压缩」菜单,后者会塞进 __MACOSX 元数据目录,徒增噪音。一个干净做法是:进入构建输出目录,把当前目录内容打包到上一层级的归档里,再用「解压到新位置」验证 manifest 是否处于顶层。

版本号也有硬性约束:manifest 里的 version 最多四段点分整数,每段 0--65535;每次上传都必须严格大于此前任何一次上传的版本,版本号不可复用、不可回滚到字面旧号。哪怕只是修一行,也要 bump 版本。另外,manifest 里的 name 与 description 应当与商店商品页一致,不一致会被视为 bait-and-switch。


六、商店素材:图标、截图、简介的隐性门槛

商品页的素材有几条常被忽视的硬指标:

  • 128×128 的 PNG 图标(单独上传,区别于 manifest 内引用的工具栏图标),它出现在搜索结果与安装按钮上。
  • 至少一张截图 ,尺寸 1280×800 或 640×400,PNG 或 24 位 JPG,不允许透明通道(alpha)。截图必须真实反映插件功能,不能带测试文字、不能放营销浮夸图。建议给到 5 张以内、把真实 UI 摆出来。
  • 简短摘要控制在 132 字符以内,详细描述要解释「价值」而非「实现」。标题尽量短、清晰、不超过 45 字符。
  • **分类(Category)**要选最贴合的一项。
  • 可选但建议的推广图:小型推广磁贴 440×280、横幅 1400×560,用于争取精选位曝光。

一张真实截图胜过一打形容词。审核员会核对截图与描述功能是否对得上------「截图不反映所述功能」本身就是一个独立驳回项。所以截图请直接截真实界面,不要 P 图。


七、最容易被卡的一步:Privacy practices 填写

根据大量一线反馈,多数驳回其实不是代码问题,而是「隐私申报表没填对、与 manifest 实际请求对不上」。提交前你会遇到一个 Privacy practices 标签页,字段逐一看:

  1. 单一用途说明(Single Purpose):一句话讲清扩展的核心功能。这里最忌写得太泛------「提高效率」「增强体验」这类空话会被打回;必须是具体、可验证的功能句,例如「本扩展的唯一用途是帮助用户在网页阅读时标记、管理与记忆单词内容」。
  2. 权限理由(Permission justification):manifest 里用到的每个权限,各有一个文本框要求解释为什么需要。空着、或复制粘贴的通用理由(如「用于功能」)会被标记。正确写法是「用 storage 权限在本地保存用户创建的标记数据,以便后续浏览继续使用」这种一句一权限的具体说明。
  3. 远程代码声明(Remote Code):明确选「否,我没有使用远程代码」。一旦误选「是」,审核等级立即抬升;能不用就别用。
  4. 数据使用披露(Data usage) :勾选你是否收集个人身份信息、健康信息、财务信息或浏览活动;少报即使是无意的,也按政策违规处理。还要勾选并确认:不出售用户数据、不用于广告、不用于信用评估------这是发布的硬门槛。
  5. 有限使用认证(Limited Use certification):在提交被接受前,必须勾选确认遵守开发者计划政策。
  6. 隐私政策链接:即便你不收集任何数据,也建议放一个「声明零收集」的一页式政策 URL,这能直接消掉审核员的一个常见疑问;若你确实碰用户数据,这条链接是必填且会被点开核验(404 直接挂)。

OmniPic 这类「模型随包走、推理全本地」的扩展,在填写时反而轻松:数据使用披露可以干净地声明「不收集、不上传」,权限清单也极短,审核路径自然更短。这也反向说明:本地优先的架构不仅保护用户,也保护你自己的过审体验。


八、提交与审核:时间线、可见性与分级发布

填完商品页与隐私申报,点提交,后台状态变为「Pending review」。审核是「自动扫描 + 人工复核」的混合:权限窄、无远端数据收集的简单扩展,常常几小时到一两天内自动通过;而请求宽泛 host 权限、全站注入内容脚本、或触碰敏感 API 的扩展,几乎必然进人工队列,可能拖到数周。经验法则是:按一周来规划,比预期快就当赚到,并且绝不要把发布会与未过审的提交绑死排期。

可见性(Visibility)有三种,且无论哪种都要过审,可见性不是跳过审核的捷径:

  • Public:上架、可被搜索、任何人可装。
  • Unlisted:不进搜索与分类浏览,但拿到直链的人都能装------适合用自己站点分发、或先放真实用户公测。
  • Private:限定到指定测试者或 Google Workspace 域名内,企业内工具的常规路线。

你还可以「先过审、后手动发布」,把上架时机留到与别的动作对齐。对于 nontrivial 的更新,后台支持分级发布(Staged rollout),先放给一定比例的用户,指标崩了立刻停------这是把回归损失关进笼子里的最实用开关。


九、常见驳回原因与修复

把高频驳回按出现频率排一下,基本就是这份清单:

  1. 权限与功能不匹配(头号原因):请求的权限超出扩展可见行为。修复方式是 trim manifest,而不是重写理由去争辩。
  2. 单一用途违规:做了几件不相干的事。修复方式是拆扩展或砍功能。
  3. 误导或垃圾元信息:关键词堆砌(标题里塞满「最好/第一/免费」)、在标题写竞品名、声称做不到的能力。规则很简单------读起来像 spam 就重写。
  4. 隐私披露缺失或不充分:收集了数据却没申报,或隐私政策链接 404。审核员会真的点开那个链接。
  5. 混淆代码或远程代码:MV3 下不可商量。压缩(minify)没问题,混淆(obfuscate)与远程加载代码直接拒。
  6. 最低功能(Minimum functionality):只是一个网站书签、或没有浏览器层功能的薄壳,不达标。
  7. 审核时跑不起来:审核员装不上或跑不通。凡是登录后才有的功能,务必在给审核员的备注里填好测试账号与步骤。

被驳回时邮件会引用具体政策条款,并通常给一句简短说明。正确动作是:只修被点名的问题、bump 版本、原渠道 resubmit。如果你确信驳回是事实错误,再走申诉(appeal)流程;把「不同意」当首次回应去申诉,往往无效。反复提交不合规的版本,甚至可能把账号本身置于风险中。


十、上架之后:更新、版本号与权限债务

你只会「第一次」上架一次;之后拼的是更新习惯。每一条更新都要过审,没有小改动快通道,所以把修复批量打包,而不是一周发五个一行补丁。每次都必须 bump 版本;上传与历史版本号相同的包,会在进审核前就被拒。

新增权限是一笔「信任债务」:Chrome 会在更新请求新权限时禁用扩展并提示用户重新授权,不少人从此不再启用。所以权限集合尽量在首发时一次定准,事后追加代价很高。对任何非平凡的更新用分级发布;盯后台的装机、卸载、曝光数据------曝光高但安装低,通常是简介或截图的问题。公开回复用户评价,一个可见的客服存在会切实改变潜在安装者的观感。保持商品页新鲜:展示旧 UI 的截图、描述已删功能,都会成为元数据准确性问题,上线很久后仍可能被标记。


十一、跨端:Firefox AMO 与 Edge 的额外功课

如果你的目标不止 Chrome,Edge 大体复用 Chrome 的 MV3 模型,迁移成本低;但 Firefox 的 AMO 是另一套功课 。它要求 manifest 里有 browser_specific_settings.gecko.id(Chrome 会忽略这个键,可以共用一份 manifest);AMO 还要求源码提交 ------必须附上完整源码、构建步骤说明与 lockfile,且构建要可复现、与发布包 diff 干净,不允许混淆。OmniPic 在 AMO 上的 ID 就是 omnipic-studio@eden.dev,gecko.id 与 Chrome 端保持一致,正是为了跨端同一身份。

至于 Edge,它复用 Chrome 的扩展模型,大部分 MV3 扩展在 Edge Add-ons 里几乎零改动就能提交,主要差异集中在商店后台的元数据字段与审核时长,真正需要额外功课的仍是 Firefox 的 AMO。换句话说,跨端成本的结构是:Chrome 与 Edge 共用一套 MV3 代码,Firefox 多一份源码提交与同意框架的对齐工作。把这套结构在立项时就想清楚,比上线后再补跨端要省心得多。

另外一条 2026 年的新约束:Mozilla 在 2026 上半年要求所有扩展 (含存量,下次更新时)采用内置的数据收集同意框架;新扩展自 2025-11-03 起已强制。也就是说,跨端不只是「代码能跑」,还包括各商店各自的隐私与同意机制对齐。好消息是,Chrome 148(2026 年 5 月)起在 Chrome 里也能直接用 browser.* 这个 promise 化命名空间,Firefox/Edge 的跨端可移植性比以前好不少。


十二、给独立开发者的落地清单

把上面十几节压成一张可勾选清单,提交前逐项过一遍:

  • 开发者账号:付过一次性 5 美元、开启 2SV、验证联系邮箱、设好显示名、声明经营者身份。
  • 架构:MV3(service_worker、declarativeNetRequest、严格 CSP、零远程代码)。
  • 权限:每项都在代码里有真实调用;host 用具体域名;activeTab 优先;无多余权限。
  • 单一用途:一句能验证的核心功能,无不相干功能堆砌。
  • 打包:manifest 在 ZIP 根目录;剔除 node_modules / 源码映射 / .git;用命令行 zip 避免 __MACOSX;版本号已 bump。
  • 素材:128×128 图标、≥1 张 1280×800/640×400 无透明截图、≤132 字符摘要、选好分类。
  • 隐私申报:单一用途句、逐权限理由、远程代码选否、数据披露勾全、有限使用认证、隐私政策 URL 可用。
  • 可见性与发布:选 Public/Unlisted/Private;非平凡更新用分级发布;不把发布会绑死未过审提交。
  • 跨端(如需要):AMO 的 gecko.id 与可复现源码提交、数据同意框架已对齐。

这张清单的价值在于:它把「审核」从玄学变成可逐项验收的工程清单。多数驳回,都能在提交前被它拦下。


十三、结语与获取

入驻 Chrome 插件市场,难的从来不是写代码,而是把「权限、隐私、单一用途」这三件事在提交前就做对。Manifest V3 把远程代码、常驻后台、阻塞式请求都收进了更安全的形态,审核也相应更看重「你声明的和代码里做的是否一致」。把数据留在本地、把权限收到最窄、把用途讲到一句可验,过审体验会顺得多------这既是政策要求,也是工程上更耐操的做法。

Omni Suite 六款扩展正是按这套思路一个个搬上架的:模型随包走、联机走点对点、推理进 worker、失败先降级。如果你也在做本地优先的端侧产品,或对其中某款组件的上架细节感兴趣,欢迎到官网交流。

相关推荐
悟天特斯1 小时前
安防一体化:从“各管各的“到“全局联动“
java·大数据·网络·人工智能·物联网
腾讯数据架构师1 小时前
任务跑完怎么直接出图表?CubeStudio 任务可视化 ECharts 数据格式实操(CSV/JSON + metric.json,11 种图表一键渲染)
前端·json·echarts·数据可视化
小小小米粒1 小时前
不是在构造方法「之前」修饰 Bean、注入;是构造方法跑完之后,才做属性注入,再跑 @PostConstruct。
前端
小李科技2 小时前
【性能优化】事件委托:目标定位与 React/Vue 实战
前端·vue.js·react.js·面试·性能优化·前端框架
QianhangQianping2 小时前
一块大屏的数据在浏览器里怎么变成画面:背景、子屏、前景三层结构
前端·低代码·架构·编辑器·数据可视化·大屏可视化
梦想很大很大2 小时前
让 Codex 自由发挥,给 nvm-desktop 换个 UI
前端·人工智能·设计
蓝莓味的口香糖2 小时前
【VUE】【CSS】Vue移动端适配主流方案总结
前端·css·vue.js
geovindu2 小时前
SQL Data Sampling and Approximation Techniques using postgreSQL 18
大数据·数据库·数据仓库·sql·postgresql·数据库开发·数据库架构
shennv8882 小时前
接入大模型流式输出后,文字偶尔乱码?问题可能出在前端
前端