Web 应用的覆盖面非常广。它们在多个平台上运行。通过链接可以轻松分享这些链接。但传统上,它们缺乏与操作系统的集成。不久之前,它们甚至还无法安装。幸运的是,这种局面已经改变,现在我们可以利用这种集成,为 PWA 添加实用功能。我们来了解一下其中的一些选项。
使用文件系统
使用文件的典型用户工作流如下所示:
- 从设备中选择一个文件或文件夹,然后直接打开。
- 更改这些文件或文件夹,然后直接保存更改。
- 新建文件和文件夹。
在 File System Access API 推出之前,Web 应用无法执行此操作。打开文件需要上传文件,保存更改后,用户必须下载这些文件,而网络则完全没有权限在用户文件系统中创建新文件和文件夹。
打开文件
我们使用 window.showOpenFilePicker()
方法来打开文件。请注意,此方法需要用户手势,例如按钮点击。以下是用于打开文件的其余设置:
- 从文件系统访问权限的文件选择器 API 中捕获文件句柄。这可为您提供该文件的基本信息。
- 使用句柄的
getFile()
方法,您将获得一种名为File
的特殊Blob
,其中包含文件的其他只读属性(例如名称和上次修改日期)。由于它是 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 上捕获网址。
对于桌面浏览器,网络浏览器社区创建了一个新规范。此规范目前处于实验阶段;它会添加新的清单文件成员: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 scheme,例如 pwa://
。在多种操作系统中,安装式应用通过注册其架构来获得此功能。
对于 PWA,此功能需使用 网址 Protocol Handler 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 scheme 连接到用户账号中的任何其他已安装应用(无论是否为 PWA)所有平台的设备您只需创建一个链接或使用 navigator.href
,并指向所需的 URI 架构,并以网址转义形式传递参数。
您可以使用众所周知的标准架构,例如 tel:
(用于拨打电话)、mailto:
(用于发送电子邮件)或 sms:
(用于文本消息);您也可以了解其他应用的网址方案,例如知名消息服务、地图、导航、在线会议、社交网络和应用商店中的网址架构。
网络共享
浏览器支持
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
借助 Web Share API,您的 PWA 可以通过共享渠道将内容发送到设备中的其他已安装应用。
此 API 仅适用于具有 share
机制的操作系统,包括 Android、iOS、iPadOS、Windows 和 ChromeOS。
您可以共享包含以下内容的对象:
- 文本(
title
和text
属性) - 网址(
url
资源) - 文件(
files
属性)。
如需检查当前设备是否可以共享内容,对于文本等简单数据,您需要检查是否存在 navigator.share()
方法;如需共享文件,您需要检查是否存在 navigator.canShare()
方法。
通过调用 navigator.share(objectToShare)
来请求共享操作。该调用会返回一个使用 undefined
进行解析或拒绝并返回异常的 Promise。
网络共享目标
Web Share Target API 可让您的 PWA 成为该设备上其他应用的共享操作的目标,无论该应用是否为 PWA。您的 PWA 会接收其他应用共享的数据。
它目前可通过 WebAPK 和 ChromeOS 在 Android 设备上使用,并且只有在用户安装您的 PWA 后才能运行。用户安装应用后,浏览器会在操作系统中注册分享目标。
您可以使用“网络共享目标”草稿规范中定义的 share_target
成员在清单中设置网络共享目标。share_target
设置为具有一些属性的对象:
action
- 将在预计接收共享数据的 PWA 窗口中加载的网址。
method
- 操作将使用 HTTP 动词方法,例如
GET
、POST
或PUT
。 enctype
- (可选)参数的编码类型,默认为
application/x-www-form-urlencoded
,但对于POST
等方法,也可以将其设置为multipart/form-data
。 params
- 一个对象,它会将共享数据(来自网络共享中的键:
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 从 window.location
字符串中读取该数据,只需使用 URL
构造函数解析该字符串即可。
浏览器将使用清单中的 PWA 名称和图标来提供操作系统的共享条目。您无法为此目的选择其他集合。
如需查看更详细的示例以及如何接收文件,请参阅使用 Web Share Target API 接收共享数据
联系人选取工具
浏览器支持
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
借助 Contact Picker API,您可以请求设备呈现包含所有用户联系人的原生对话框,以便用户选择一个或多个联系人。然后,您的 PWA 就可以从这些联系人接收您需要的数据。
Contact Picker 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.
}
}