首页 / 浏览器扩展开发入门教程 / 兼容清单与常见坑

浏览器扩展开发入门教程

兼容清单与常见坑

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

兼容清单跨浏览器safarichrome-incompatibilities排查差异表

本节目标:学完你能拿着一份 Chrome↔Firefox 差异清单自查,知道 Safari 哪些 API 受限,并掌握”先查兼容表、再做特性检测、最后分浏览器调试”的排查套路。

前面两节解决了”写法统一”。但扩展要在多家浏览器跑通,还有第二关:能力差异。有的 API 这家有、那家没有;有的方法参数这家多、那家少。这一节把常见差异、Safari 的限制和排查思路一次讲清。

53-1 Chrome 与 Firefox 差异清单

先给一张高频差异表,写代码时对照自查:

维度Chrome / EdgeFirefox
API 命名空间chrome.*browser.*(也兼容 chrome.*
异步风格回调为主,Chrome 121+ 支持 PromisePromise 化
后台模型background.service_worker,事件驱动background.service_worker,事件驱动(细节略有差异)
专属清单字段browser_specific_settings.gecko.id
侧边栏side_panelsidebar_action(两者互不兼容)
部分 API 覆盖广个别方法不支持或行为不同

需要更新的认知:从 Chrome 148 起,Chromium 也原生提供了 browser 命名空间(Chrome 152 起覆盖全部扩展场景,含 devtools),“Chrome 只有 chrome.*”的说法已不再成立。Mozilla 的 webextension-polyfill 也已宣布冻结、不再更新。polyfill 现在的定位是兼容旧版 Chrome 与统一写法的过渡方案,新项目可以评估直接用原生 browser.*

实际开发里,差异大多落在”某个方法在 Firefox 上不支持”或”参数含义微调”。例如通知 API 的部分回调事件、某些标签页方法。这些细节上,Firefox 与 Chrome 并非百分百对齐。权威做法是查 MDN 的 “Browser support for JavaScript APIs” 兼容表,每个 API 页都带各浏览器支持标记。

// 不要假设某方法家家都有,发布前查 MDN 兼容表
// 例如 storage、tabs、scripting 各方法的 Firefox/Chrome 标记
Note

一个实用经验:先以 Chrome(MV3 主线)写完功能,再在 Firefox 用 about:debugging 加载临时扩展跑一遍。报错的 API 就是差异点,比纯靠记忆更可靠。

53-2 Safari 的受限 API

Safari 也实现 WebExtensions,但它是”子集”实现,限制最多。关键点先说清:Safari 同时支持 chrome.*browser.* 两种命名空间,也同时支持回调和 Promise。正因如此,它和 polyfill 相处得不错。但能力覆盖是短板。

常见限制(以当前 Safari 版本为准,发布前再核对 MDN):

  • storage.sync:本地存储机制可用,但跨设备同步不支持
  • identity:不支持,OAuth 登录要改在新标签页里做。
  • runtime.setUninstallURL / runtime.onUpdateAvailable:不支持。
  • permissions.webRequestBlocking:不支持;webRequest 在 iOS 上也不支持阻塞。
  • devtools:较新 Safari(16+)才支持。
  • scripting.executeScriptinjectImmediately 等参数不支持。
  • cookies.onChanged 等部分事件不支持。
  • update_url:不支持,Safari 扩展更新走 App Store。

另外,Safari 会忽略清单里不支持的字段,不会报错。这既是好事(不会崩),也是坑:你以为配了,却没生效。Safari 还忽略 manifest 权限里的 file:// 协议,用到要自己兜底。

{
  "browser_specific_settings": {
    "safari": {
      "strict_min_version": "16.0"
    }
  }
}
Tip

Safari 扩展最终要包进一个 App、走 App Store 上架,不能直接传 zip 到商店。它的分发链路和 Chrome Web Store / Firefox Add-ons 完全不同,规划时就得算进去。

另外,iOS 上的 Safari 限制比 macOS 更多。比如 windows 的部分创建与关闭方法、tabs.move、上下文菜单,在 iOS 上都不支持。如果你的扩展要覆盖 iPhone 和 iPad,得额外按 iOS 的兼容表再查一遍。不能只看 macOS 版 Safari 的支持情况,否则上线后才发现移动端功能缺失。

53-3 用特性检测兜底

能力缺失不能靠 polyfill 变出来,得在代码里自己判断。思路是:用之前先确认这个 API 或方法在运行时存在。

// 特性检测:方法不存在就走降级
async function saveSync(key, value) {
  if (browser.storage.sync) {
    try {
      await browser.storage.sync.set({ [key]: value });
      return;
    } catch (err) {
      console.warn("sync 失败,回退 local", err);
    }
  }
  // Safari 等不支持 sync 的环境走 local
  await browser.storage.local.set({ [key]: value });
}

这种”先试主路径、失败回退”的写法,能让一份代码在能力不同的浏览器上都优雅降级。它不会直接抛错崩溃。

// 检测某个 API 是否存在
if (typeof browser.identity !== "undefined") {
  // 走 identity 登录
} else {
  // 走新标签页 OAuth
}

53-4 各浏览器调试入口

排查跨浏览器问题,得知道去哪看:

  • Chrome / Edgechrome://extensions 开开发者模式,Load Unpacked 加载,点服务工作者(Service Worker)链接看后台日志。
  • Firefox:访问 about:debugging#/runtime/this-firefox,点”临时载入附加组件”,选 manifest.json,即可加载并查看控制台。
  • Safari:先在”开发”菜单开启”允许未签名扩展”。扩展跑在 Safari 里,用 Web 检查器看日志。
Note

同一份代码,在 Firefox 用 about:debugging 跑一遍,在 Chrome 用 chrome://extensions 跑一遍。两边都能跑通,才叫真跨浏览器。只在一家居然不算。

53-5 一套排查套路

把前面的串成流程。这套流程不必一次全做。先查兼容表、再分浏览器实测,已经能挡掉绝大多数跨浏览器问题。等真遇到缺失能力,再回头补特性检测。

  1. 写之前查兼容表:MDN “Browser support for JavaScript APIs” 标了每个 API 在各浏览器的支持情况,先避坑。
  2. 统一写法:全项目 browser.* + polyfill,别混 chrome.*
  3. 特性检测兜底:对可能缺失的 API 做存在性判断和降级。
  4. 分浏览器实测:Firefox 用 about:debugging、Chrome 用开发者模式、Safari 用 Web 检查器,逐个加载验证。
  5. 清单分变体:用构建脚本产出带 browser_specific_settings 的各家清单。
// 排查时的通用日志模板
try {
  const res = await browser.tabs.query({ active: true });
  console.log("当前标签", res);
} catch (err) {
  console.error("该浏览器可能不支持此用法", err);
}

53-6 Edge 几乎等同 Chrome

提跨浏览器,常被人忽略的是 Edge。Edge 基于 Chromium 内核,扩展 API 与 Chrome 几乎完全一致:命名空间是 chrome.*、异步风格相同、清单字段相同。所以只要你按 Chrome(MV3 主线)写、再用 polyfill 兼容 Firefox,Edge 基本”免费”就能跑。

真正不同的是分发链路:Edge 走 Edge Add-ons 商店,审核节奏和 Chrome Web Store 不同,但代码不用改动。一个实用提醒是:商店托管(Chrome Web Store / Edge Add-ons)的扩展会自动更新,清单里不需要配 update_url。只有自托管分发才需要声明它(见第 50 章),构建清单分变体时基本不用操心这个字段。

浏览器内核命名空间分发渠道
ChromeChromiumchrome.*Chrome Web Store
EdgeChromiumchrome.*Edge Add-ons
FirefoxGeckobrowser.*Firefox Add-ons
SafariWebKit两者都支持App Store
Tip

跨浏览器工程的优先级建议:先打通 Chrome + Edge(几乎零成本),再用 polyfill 接 Firefox,最后按需兼容 Safari 的子集能力。这样投入产出比最高。

53-7 小结

跨浏览器三件事:

  1. 写法统一靠 polyfill,命名空间和异步风格不再是障碍。
  2. 能力差异靠清单自查 + 特性检测,缺失就降级。
  3. Safari 最受限、Edge 最接近 Chrome:Safari 是子集实现、走 App Store;Edge 等同 Chrome,基本免费兼容。

到这,模块十二的跨浏览器兼容就讲完了。你已经有了一套代码跑 Chrome、Firefox、Edge 的思路,Safari 也能按需兼容。下一模块我们转向现代构建工具链,看怎么用 Vite 把这套跨浏览器工程真正跑顺。