scope

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

scope 清单成员用于指定包含你的 Web 应用页面和子目录的顶级 URL 路径。当用户安装和使用你的 Web 应用时,scope 内的页面会提供类似应用界面的体验。当用户导航到应用 scope 外的页面时,他们仍然会体验到类似应用界面的体验,但浏览器会显示 URL 栏等 UI 元素,以表明上下文已更改。

语法

json
/* Absolute URL */
"scope": "https://example.com/myapp/"

/* Relative URL */
"scope": "/myapp/"

/* Scope limited to a specific directory */
"scope": "/myapp/dashboard/"

scope

表示 URL 的字符串。URL 可以是绝对的也可以是相对的。如果值为相对值,则会相对于清单文件的 URL 进行解析。

如果清单中未指定 scope,或者值无效(即不是字符串、不是有效 URL,或者 start_url 不在指定的 scope 内),则有效 scope 将被设置为 start_url 值,并去除其文件名、查询和片段。

描述

scope 成员定义了属于你的 Web 应用已安装体验的 URL。浏览器使用 scope 来确定一个页面是否在你的 Web 应用的 应用上下文 内。

Scope 内外行为

如果一个 URL 的路径以 scope 中定义的 URL 路径开头,则该 URL 被视为“在 scope 内”。例如,如果 scope 设置为 /app/,那么 URL /app//app/page.html/app/dashboard/index.html 都被视为在 scope 内,而 //page.html 则不在。

当用户打开你已安装的 Web 应用时,他们会看到一个类似应用界面的体验。对于 scope 内的页面,浏览器会维护应用上下文并保留类似应用界面的体验。当用户导航到应用 scope 外的页面时,他们仍然会大致体验到类似应用界面的体验;但是,在这些页面上,浏览器会显示额外的 UI 元素,如 URL 栏。这有助于用户了解他们正在查看的页面超出了应用定义的 scope。

注意: scope 成员不会阻止用户导航到 scope 外的应用页面。浏览器不会阻止 scope 外的导航,允许它们在新启动的顶级浏览上下文中打开。

考虑一个用于探索徒步小径的 Web 应用,其目录结构如下

web-app/
├── manifest.json
├── trails/
│   ├── index.html
│   ├── trail-list.html
│   ├── settings/
│   │   └── index.html
│   └── saratoga-gap-trail.html
├── blog/
│   └── index.html

scope 设置为 /trails/

  • 在查看 /trails/ 下的页面和子目录(如 trail-list.html/trails/settings/index.html)时,用户将体验到类似应用界面的体验,而没有浏览器控件(左侧图像)。
  • 当导航到子目录中的页面(如 /blog/)时,这些页面超出了应用的 scope,但应用界面的体验仍然存在,只是用户会看到网站地址和其他浏览器控件(右侧图像)。
Scope 内页面 Scope 外页面
Trail listing page showing app-like interface without browser controls Blog page showing website address and browser controls while maintaining app-like interface

Scope 对深度链接页面的影响

其他应用可以直接深度链接到你的 Web 应用的特定页面。scope 成员会影响这些深度链接页面的显示方式,但它不是深度链接工作的必需项。

以之前探索徒步小径的 Web 应用为例,其中 scope 设置为 /trails/

  • 如果在社交媒体上分享到 https://trailnav.app/trails/saratoga-gap-trail.html 的链接,已安装 Trail Navigator 应用的用户将会在应用的界面中查看此页面,而没有浏览器控件。
  • 如果分享的链接是 https://trailnav.app/blog/trail-safety.html,这些用户将会在类似应用界面的体验中查看博客页面,但会显示网站地址和浏览器控件,因为该页面超出了应用定义的 scope。

这种行为即使在通过外部链接访问应用页面时,也能帮助用户了解他们查看的页面是否在应用 scope 内或外。

Fallback Scope 行为

如果 start_url 不是 scope URL 的子集,则 scope 无效。例如:

  • 有效scope/app/start_url/app/home.html
  • 无效scope/app/start_url/index.html

如果 scope 缺失或无效,它将默认为 start_url 值,并去除其文件名、查询和片段。请注意,如果 start_url 也未定义(或无效),它将默认为链接到清单的页面。这确保了默认情况下,scope 将从触发安装的页面开始。

例如

  • 如果 start_urlhttps://example.com/app/index.html?user=123#home,则 scope 将是 https://example.com/app/
  • 如果 start_url/pages/welcome.html,则 scope 将是同一域下的 /pages/
  • 如果 start_url/pages/(尾部斜杠很重要),则 scope 将是 /pages/

如果你依赖 scope 的 fallback 行为,请确保你应用中所有页面的 URL 都以 start_url 的父路径开头。为了避免以这种方式确定 scope 的问题,建议在你的清单文件中明确指定 scope

Scope 匹配机制

scope URL 的字符串匹配采用简单的前缀匹配,而不是路径结构。例如,如果 scope 设置为 /prefix,它将匹配以 /prefix 开头的 URL,包括 /prefix-of/index.html/prefix/index.html。请注意,/prefix-of/index.html 匹配,即使 prefix-of 与 scope /prefix 不是精确匹配。

因此,建议定义一个以 / 结尾的 scope。将 scope 设置为 /prefix/ 可确保它只匹配 /prefix/ 目录内的页面,从而防止意外匹配。

示例

为 scope 指定绝对 URL

假设你的 Web 应用的清单文件链接自 https://hikingapp.com/index.html,并且你希望 scope 包含所有子目录。你可以使用与清单文件 URL 同源的绝对 URL 指定此 scope,如下所示。这确保了像 https://hikingapp.com/storehttps://hikingapp.com/company 这样的页面属于你的 Web 应用。

json
{
  "scope": "https://hikingapp.com/"
}

为 scope 指定相对 URL

如果你的清单文件的 URL 是 https://hikingapp.com/resources/manifest.json,并且你希望 scope 是 https://hikingapp.com/app/,你可以将其定义为相对 URL

json
{
  "scope": "../app/"
}

为网站的特定部分定义 Web 应用

如果你有一个包含多个部分的网站,但你想让你的 Web 应用专注于一个特定部分,你可以将 scope 定义为

json
{
  "name": "My Hiking Web App",
  "start_url": "https://hikingapp.com/store/",
  "scope": "https://hikingapp.com/store/"
}

通过这种设置,像 https://hikingapp.com/store/products 这样的页面属于你的 Web 应用,但 https://hikingapp.com/company/ 超出了你 Web 应用的 scope。对于 scope 外的 URL,浏览器可能会显示不同的 UI 元素,让用户知道他们已离开应用的 scope。

规范

规范
Web 应用清单
# scope-member

浏览器兼容性

另见