Manifest · 清单成员
scope_extensions 清单成员
发布于
scope_extensions 是一个源的数组,列出已安装 Web 应用希望纳入自身作用域的其他源,这样
support.example.com 或 example.co.uk 就能在应用窗口内打开,而不出现超出作用域的提示条。清单的
scope 成员只能覆盖一个源;该成员是让应用跨越多个源的双向握手,每个额外的源都要在
/.well-known/web-app-origin-association 文件里确认这层关联。
Chrome 138、Edge 138、Android WebView 138 与 Samsung Internet 30.0 发布了该成员(BCD
html.manifest.scope_extensions);Chrome 曾在 121 到 126 以源试用形式提供,并自 115 起放在
about://flags/#enable-desktop-pwas-scope-extensions 标志之后。Firefox 157 与 Safari 27 不读取它,
会静默丢弃该成员。
- 类型:对象数组。Manifest Incubations 说明文档与 MDN 把每一项写作
{ "type": "origin", "origin": "https://support.example.com" };Chrome 为源试用撰写的开发者文档 省略type,写作{ "origin": "..." }。origin是一个 HTTPS 源,可以带*.通配标签以覆盖 全部子域,例如https://*.example.com。 - 默认值:空数组;应用的作用域就是单源的
scope成员。 - 示例值:
[{ "type": "origin", "origin": "https://*.example.com" }]。
只有当浏览器从所列的源抓取到 https://<origin>/.well-known/web-app-origin-association 并在其中
找到应用的清单 id 时,该条目才生效。两份来源对这个文件的形状同样不一致:说明文档与 MDN 以应用
id 为键,{ "https://example.com/app": { "scope": "/" } },其中可选的 scope 把扩展收窄到被扩展
源上的某个路径;Chrome 的源试用文档则写作
{ "web_apps": [{ "web_app_identity": "https://example.com" }] }。按你的目标 Chromium 版本能校验
的形状提供文件,并把这层关联视为一份信任声明:列出某个应用的源,等于允许该应用把自己的页面
当作这个源的页面来展示。
权限不会随作用域扩展一起转移。在 example.com 应用窗口里打开的 support.example.com 页面保留
support.example.com 自己的权限状态、存储与 Cookie;改变的只有窗口外观。
清单与关联文件是同一份声明拆在两台服务器上;第三个示例是两者就位后页面能了解到什么。
把应用扩展到支持子域与国家域名
Section titled “把应用扩展到支持子域与国家域名”位于 https://example.com/app 的主应用列出两个额外的源。通配形式覆盖 example.com 的所有子域,
所以 support. 与 help. 不需要单独条目;国家域名是另一个可注册域,需要单独列出。
{ "id": "/app", "name": "Example", "start_url": "/app/index.html", "scope": "/app", "display": "standalone", "scope_extensions": [ { "type": "origin", "origin": "https://*.example.com" }, { "type": "origin", "origin": "https://example.co.uk" } ]}每个列出的源都要自己作答;example.co.uk 上缺失或格式错误的关联文件只会让这个源留在作用域外,
子域仍然正常工作。
在被扩展的源上提供关联文件
Section titled “在被扩展的源上提供关联文件”https://example.co.uk/.well-known/web-app-origin-association 以 application/json 类型、无需认证
地提供 JSON。说明文档的形状以应用完整的清单 id 为键,并把扩展限定到某个路径。
{ "https://example.com/app": { "scope": "/" }}对于校验源试用形状的 Chromium 版本,同一声明写作
{ "web_apps": [{ "web_app_identity": "https://example.com/app" }] }。一个文件里无法同时发布两种
形状,所以安装后在 chrome://web-app-internals 中检查解析结果。
让页面知道自己是否处于扩展后的应用窗口内
Section titled “让页面知道自己是否处于扩展后的应用窗口内”没有任何 API 会报告某次导航是否被接受为作用域内。页面能观察到的是显示模式:support.example.com
上的文档发现自己处于 standalone,说明它是在应用窗口里打开的,在 Chrome 138 及之后这意味着扩展
通过了校验。回退分支是浏览器标签页,那里指向关联源的链接表现为普通的跨源导航。
const inAppWindow = ['standalone', 'minimal-ui', 'window-controls-overlay'] .some((mode) => matchMedia(`(display-mode: ${mode})`).matches);
if (inAppWindow) { document.body.classList.add('in-app'); // 隐藏营销页头,保留应用导航} else { // 浏览器标签页,或没有 scope_extensions 的引擎:指向 example.com 的链接 // 作为普通导航打开,在旧版应用窗口里可能显示超出作用域的提示条。 document.body.classList.add('in-tab');}两条分支里的导航本身保持一致:无论扩展是否被遵循,location.assign() 到关联源都是正确做法,
显示什么外观由浏览器决定。
- scope 清单成员
- id 清单成员
- handle_links 清单成员
- Scope Extensions for Web App Manifest (explainer)(github.com)
- Web app scope extensions(developer.chrome.com)
- scope_extensions(developer.mozilla.org)
规范
| 规范 | 状态 |
|---|---|
| Web 应用清单:scope_extensions | 说明文档 |
| Web Application Manifest: scope member | W3C |
- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Desktop) | 支持 | 138 | 高 | 来源 | — |
| Chrome (Android) | 支持 | 138 | 高 | 来源 | 1 |
| Edge (Desktop) | 支持 | 138 | 高 | 来源 | 2 |
| Firefox (Desktop) | 不支持 | — | 高 | 来源 | 3 |
| Firefox (Android) | 不支持 | — | 高 | 来源 | 45 |
| Safari (macOS) | 不支持 | — | 高 | 来源 | 6 |
| Safari (iOS) | 不支持 | — | 高 | 来源 | 78 |
| Samsung Internet | 支持 | 30.0 | 高 | 来源 | 9 |
| WebView (Android) | 支持 | 138 | 高 | 来源 | 10 |
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- browser-compat-data 未记录 Firefox 的支持。
- browser-compat-data 未记录 Firefox for Android 的支持。
- 由 browser-compat-data 镜像自 Firefox 的数据推导。
- browser-compat-data 未记录 Safari 的支持。
- browser-compat-data 未记录 iOS 版 Safari 的支持。
- 由 browser-compat-data 镜像自 Safari 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。