Web 应用的覆盖面很广。它们可在多个平台上运行。可以通过链接轻松分享。但传统上,它们缺乏与操作系统的集成。不久之前,它们甚至无法安装。幸运的是,这种情况已经改变,现在我们可以利用该集成功能为 PWA 添加实用功能。我们来了解一下其中的一些选项。
使用文件系统
使用文件的典型用户工作流程如下所示:
- 从设备中选择文件或文件夹,然后直接打开。
- 对这些文件或文件夹进行更改,然后直接保存更改。
- 创建新文件和文件夹。
在 File System Access API 推出之前,Web 应用无法做到这一点。打开文件需要上传文件,保存更改需要用户下载文件,并且 Web 根本无法在用户的文件系统中创建新文件和文件夹。
打开文件
如需打开文件,请使用 window.showOpenFilePicker()
方法。请注意,此方法需要用户手势,例如点击按钮。以下是打开文件的其余设置:
- 从文件系统访问的文件选择器 API 中捕获文件句柄。这会显示有关该文件的基本信息。
- 使用句柄的
getFile()
方法,您将获得一种特殊的Blob
,称为File
,其中包含有关文件的其他只读属性(例如名称和上次修改日期)。由于它是 Blob,因此可以对其调用 Blob 方法(例如text()
)来获取其内容。
// Have the user select a file.
const [ handle ] = await window.showOpenFilePicker();
// Get the File object from the handle.
const file = await handle.getFile();
// Get the file content.
// Also available, slice(), stream(), arrayBuffer()
const content = await file.text();
正在保存更改
如需保存对文件的更改,您还需要用户手势;然后:
- 使用文件句柄创建
FileSystemWritableFileStream
。 - 更改直播。这不会就地更新文件,而是通常会创建一个临时文件。
- 最后,完成更改后,您需要关闭数据流,这样才能将更改从临时状态变为永久状态。
我们来看一下代码中的示例:
// Make a writable stream from the handle.
const writable = await handle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();
文件处理
借助 File System Access API,您可以从应用内打开文件,但反过来呢?用户希望将自己喜爱的应用设置为打开文件的默认应用。文件处理 API 是一项实验性 API,可让已安装的 PWA 执行以下操作:在用户设备上注册为文件处理程序,并在 Web 应用清单中指定 PWA 支持的 MIME 类型和文件扩展名。您可以为支持的扩展程序指定自定义文件图标。
注册后,已安装的 PWA 将显示为用户文件系统中的一个选项,允许用户直接在其中打开文件。 以下是 PWA 读取文本文件的清单设置示例:
...
"file_handlers": [
{
"action": "/open-file",
"accept": {
"text/*": [".txt"]
}
}
]
...
网址处理
借助网址处理功能,PWA 可以从操作系统捕获属于其范围的链接,并在 PWA 窗口中呈现这些链接,而不是在默认浏览器的标签页中呈现。例如,如果您收到一条指向 PWA 的消息,或者点击 PWA 中的深层链接(指向特定内容的网址),相应内容会在独立窗口中打开。
当使用 WebAPK 时(例如用户通过 Chrome 安装 PWA 时),Android 上会自动提供此行为。无法在通过 Safari 安装到 iOS 和 iPadOS 上的 PWA 中捕获网址。
对于桌面浏览器,Web 浏览器社区创建了一个新规范。此规范目前处于实验性阶段;它添加了一个新的清单文件成员:url_handlers
。此属性需要一个 PWA 希望捕获的来源数组。您的 PWA 的来源将自动获得授权,而每个其他来源都必须通过名为 web-app-origin-association
的文件接受该处理操作。例如,如果您的 PWA 的清单托管在 web.dev 上,并且您想添加 app.web.dev 源,则清单应如下所示:
"url_handlers": [
{"origin": "https://app.web.dev"},
]
在这种情况下,浏览器将检查 app.web.dev/.well-known/web-app-origin-association
是否存在文件,并接受来自 PWA 范围网址的网址处理。开发者必须创建此文件。在以下示例中,该文件如下所示:
{
"web_apps": [
{
"manifest": "/mypwa/app.webmanifest",
"details": {
"paths": [ "/*" ]
}
}
]
}
网址协议处理
网址处理功能可与标准 https
协议网址搭配使用,但也可以使用自定义 URI 方案,例如 pwa://
。在多个操作系统中,已安装的应用通过注册其方案来获得此能力。
对于 PWA,此功能通过 网址 协议处理程序 API 启用,该 API 仅在桌面设备上可用。您只能通过在应用商店中分发 PWA 来允许移动设备使用自定义协议。
如需注册,您可以使用 registerProtocolHandler() 方法,也可以在清单中使用 protocol_handlers
成员,并指定所需的方案和要在 PWA 上下文中加载的网址,例如:
...
{
"protocol_handlers": [
{
"protocol": "web+pwa",
"url": "/from-protocol?value=%s"
},
]
}
...
您可以将网址 from-protocol
路由到正确的处理程序,并在 PWA 中获取查询字符串 value
。%s
是触发操作的转义网址的占位符,因此如果您在某处有一个链接(例如 <a href="web+pwa://testing">
),您的 PWA 将打开 /from-protocol?value=testing
。
调用其他应用
您可以使用 URI 方案在每个平台上连接到用户设备中的任何其他已安装的应用(无论是否为 PWA)。您只需创建一个链接或使用 navigator.href
,然后指向所需的 URI 架构,并以网址转义形式传递实参。
您可以使用众所周知的标准方案,例如用于拨打电话的 tel:
、用于发送电子邮件的 mailto:
或用于发送短信的 sms:
;也可以了解其他应用的网址方案,例如来自知名即时通讯、地图、导航、在线会议、社交网络和应用商店的网址方案。
Web Share
借助 Web Share API,您的 PWA 可以通过共享渠道将内容发送到设备中安装的其他应用。
该 API 仅适用于具有 share
机制的操作系统,包括 Android、iOS、iPadOS、Windows 和 ChromeOS。
您可以分享包含以下内容的对象:
- 文字(
title
和text
属性) - 网址(
url
属性) - 文件(
files
属性)。
如需检查当前设备是否可以共享简单数据(例如文本),请检查是否存在 navigator.share()
方法;如需检查当前设备是否可以共享文件,请检查是否存在 navigator.canShare()
方法。
您可以通过调用 navigator.share(objectToShare)
请求分享操作。该调用会返回一个 Promise,该 Promise 会解析为 undefined
或拒绝并抛出异常。
Web Share Target
借助 Web Share Target API,您的 PWA 可以成为相应设备上其他应用(无论是否为 PWA)的分享操作的目标。您的 PWA 接收其他应用共享的数据。
此功能目前适用于 Android(使用 WebAPK)和 ChromeOS,并且仅在用户安装您的 PWA 后才有效。浏览器会在应用安装时在操作系统内注册共享目标。
您可以在清单中使用 Web Share Target 草稿规范中定义的 share_target
成员设置 Web 共享目标。share_target
设置为具有一些属性的对象:
action
- 将在 PWA 窗口中加载的网址,该窗口预计会接收共享数据。
method
- HTTP 动词方法将用于相应操作,例如
GET
、POST
或PUT
。 enctype
- (可选)参数的编码类型,默认为
application/x-www-form-urlencoded
,但也可以针对POST
等方法设置为multipart/form-data
。 params
- 一个对象,用于将共享数据(来自 Web Share 的键:
title
、text
、url
和files
)映射到浏览器将通过网址(在method: 'GET'
上)或使用所选编码在请求正文中传递的实参。
例如,您可以在清单中添加以下内容,以定义 PWA 仅接收共享数据(标题和网址):
...
"share_target": {
"action": "/receive-share/",
"method": "GET",
"params": {
"title": "shared_title",
"url": "shared_url"
}
}
...
在之前的示例中,如果系统中的任何应用正在分享带有标题的网址,并且用户从对话框中选择了您的 PWA,浏览器将创建指向您的来源 /receive-share/?shared_title=AAA&shared_url=BBB
的新导航,其中 AAA 是分享的标题,BBB 是分享的网址。您可以使用 JavaScript 通过 URL
构造函数解析 window.location
字符串,从而读取该数据。
浏览器将使用清单中的 PWA 名称和图标来填充操作系统的分享条目。您无法选择其他数据集来实现此目的。
如需查看更详细的示例以及了解如何接收文件,请参阅使用 Web Share Target API 接收共享数据
联系人选取工具
借助 Contact Picker API,您可以请求设备呈现一个包含用户所有联系人的原生对话框,以便用户选择一个或多个联系人。然后,您的 PWA 就可以从这些联系人那里接收您想要的数据。
联系人选择器 API 主要在移动设备上提供,所有操作都是通过兼容平台上的 navigator.contacts
接口完成的。
您可以使用 navigator.contacts.getProperties()
请求可供查询的属性,并使用所需属性的列表请求选择单个或多个联系人。
一些示例属性包括 name
、email
、address
和 tel
。当您要求用户选择一个或多个联系人时,可以调用 navigator.contacts.select(properties)
,并传递您希望返回的属性数组。
以下示例将列出选择器收到的联系人。
async function getContacts() {
const properties = ['name', 'email', 'tel'];
const options = { multiple: true };
try {
const contacts = await navigator.contacts.select(properties, options);
console.log(contacts);
} catch (ex) {
// Handle any errors here.
}
}