What's new in Safari extensions
Media & Web 进阶 20m

Safari 扩展新特性

What's new in Safari extensions

2023年6月5日

在 Apple 官方观看视频

一句话判断

Safari 17 同时支持 Manifest v2 和 v3,新增 :has() 选择器、Declarative Net Request 请求头修改、Session Storage、SVG 图标和按站点权限控制——而且 Web 扩展现在也能在 xrOS 上运行了。

这场 Session 讲了什么

Safari 扩展工程师 David Johnson 介绍了 Safari 17 中扩展功能的更新。

跨平台扩展:Web 扩展现在可以在 iOS、iPadOS、macOS 和 xrOS 上运行,一份代码覆盖全平台。xrOS 上的扩展与 iOS 版功能一致,包括脚本注入、后台运行和弹出窗口。

内容拦截器增强:新增 :has() 选择器支持,允许内容拦截规则基于子元素来精确匹配父元素。比如隐藏所有包含 .paid-promo 子元素的 .post 元素。

Declarative Net Request 更新:Safari 16.4 起支持修改请求头——可以设置、添加、删除 HTTP 请求头。新增 declarativeNetRequestWithHostAccess 权限要求。badge 文本可以自动显示操作计数(如拦截的请求数量)。

脚本 API 改进registerContentScript 系列 API 允许程序化地注册、更新和删除内容脚本,不再局限于 manifest 中的静态声明。

Session Storage:新增会话级存储区域,数据存在内存中,Safari 退出时清除。适合存储解密密钥和认证令牌等敏感数据。

按站点权限:Safari App 扩展现在也支持按站点授权,与 Web 扩展的权限模型统一。

SVG 图标:Safari 16.4 起支持单个 SVG 图标替代多尺寸 PNG。

值得深挖的点

W3C 标准化进程:Apple 担任 W3C WebExtensions Community Group 的联合主席,与其他浏览器厂商一起推进扩展 API 标准化。这意味着未来扩展的跨浏览器兼容性会持续改善。

Manifest v2 和 v3 共存:Safari 17 同时支持两个版本。Apple 建议在时机成熟时迁移到 v3,但没有强制截止日期。这与 Chrome 的策略不同——Chrome 已经宣布了 v2 的弃用时间表。

Session Storage 的安全定位:与 localStorage 不同,Session Storage 不写入磁盘。这使得它特别适合存储不应该被持久化的敏感数据。API 与其他 Storage Area 一致,迁移成本很低。

代码片段

// 内容拦截器 - :has() 选择器
{
    "trigger": { "url-filter": ".*" },
    "action": {
        "type": "css-display-none",
        "selector": ".post:has(.paid-promo)"
    }
}
// Declarative Net Request - 修改请求头
{
    "id": 1,
    "action": {
        "type": "modifyHeaders",
        "requestHeaders": [
            { "header": "User-Agent", "operation": "set", "value": "CustomAgent/1.0" }
        ]
    },
    "condition": {
        "urlFilter": "||example.com",
        "resourceTypes": ["main_frame"]
    }
}

// manifest.json 中声明权限
{
    "permissions": ["declarativeNetRequestWithHostAccess"]
}
// Session Storage - 会话级临时存储
// 数据存在内存中,Safari 退出时清除
await browser.storage.session.set({ authToken: "temp_token_123" });
const result = await browser.storage.session.get("authToken");

// 显示拦截计数
chrome.declarativeNetRequest.setExtensionActionOptions({
    displayActionCountAsBadgeText: true
});
// 动态注册内容脚本
await chrome.scripting.registerContentScripts([{
    id: "webkit-script",
    matches: ["https://webkit.org/*"],
    js: ["content.js"],
    persistAcrossSessions: true
}]);

// 更新已注册的脚本
await chrome.scripting.updateContentScripts([{
    id: "webkit-script",
    matches: ["https://webkit.org/*", "https://developer.apple.com/*"]
}]);

最佳实践

  • 迁移到 Manifest v3 但不必着急:Safari 同时支持两个版本,按自己的节奏迁移。优先利用 v3 的新功能(如 Declarative Net Request 的请求头修改)。
  • 使用 SVG 图标简化资源管理:一个 SVG 文件替代所有尺寸的 PNG,Safari 自动处理缩放。
  • 敏感数据用 Session Storage:认证令牌、解密密钥等不应该持久化的数据用 Session Storage 而非 localStorage。
  • 按站点权限提升用户信任:让用户逐站点授权,而不是一次性请求所有站点的访问权限。
  • 利用 :has() 选择器提升拦截精度:之前的 CSS 选择器只能匹配元素本身,有了 :has() 就能基于子元素内容做更精确的匹配。

还有什么值得关注

  • App Store 上已有超过 2000 个 Safari 扩展,iOS 扩展是增长最快的类别之一。
  • xrOS 上的扩展不需要额外开发——iOS/iPadOS 扩展自动兼容。
  • Apple 在 W3C 的参与意味着未来扩展 API 的跨浏览器一致性会越来越好。
  • Profiles(配置文件)和 Private Browsing(隐私浏览)模式下的扩展行为需要注意兼容性测试。
WWDC 2023