如何让 PWA 在系统级分享界面中显示在平台专用应用旁边
借助 Web Share Target API,您可以在用户安装 Progressive Web App 后,在用户系统级的分享工作表中显示该应用。如果您有可用于接收请求的服务器,此方法效果很好;但如果您没有,则很难让此方法正常运行。
在本文中,我们将使用 Workbox(一组用于为 Web 应用添加离线支持的 JavaScript 库)来创建一个完全位于 service worker 中的共享目标网址。这样一来,静态网站和单页应用无需专用服务器端点即可充当分享目标。

Share Target Test
的已安装 PWA 作为选项。
在同一页面上
如果您不熟悉 Web Share Target 的工作原理,请参阅使用 Web Share Target API 接收共享数据,其中提供了深入的介绍。 下面简要回顾一下。
实现 Web 分享目标功能需要完成两个部分。首先,更新您的Web 应用清单,以指明您希望应用在安装后成为分享目标。以下示例通过 POST
请求将分享定向到 /share
网址。它以多部分表单的形式进行编码,其中标题称为 name
,文本称为 description
,JPEG 图片称为 photos
。
…
"share_target": {
"action": "/share",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "name",
"text": "description",
"files": [
{
"name": "photos",
"accept": ["image/jpeg", ".jpg"]
}
]
}
}
…
使用 Workbox 的服务工作线程共享目标
虽然通常由服务器端点处理,但您可以为共享目标执行一个巧妙的技巧,即直接在服务工作线程中注册路由以处理请求。这样一来,您的应用就可以在没有后端的情况下成为分享目标。
您可以在 Workbox 中注册由 Service Worker 处理的路由,从而实现此目的。首先,从 'workbox-routing'
导入 registerRoute
。请注意,它已注册为 /share
路由,与示例 Web 应用清单中列出的路由相同。作为响应,它会调用 shareTargetHandler()
。
import { registerRoute } from 'workbox-routing';
registerRoute(
'/share',
shareTargetHandler,
'POST'
);
shareTargetHandler()
函数是异步的,它会获取事件,等待表单数据,然后从中检索媒体文件。
async function shareTargetHandler ({event}) {
const formData = await event.request.formData();
const mediaFiles = formData.getAll('media');
for (const mediaFile of mediaFiles) {
// Do something with mediaFile
// Maybe cache it or post it back to a server
});
// Do something with the rest of formData as you need
// Maybe save it to IndexedDB
};
然后,您可以对这些文件执行任何操作。您可以缓存这些内容。您可以通过提取请求将它们发送到某个位置。您甚至可以使用其他清单选项,例如,提供包含一些查询参数的网页,以用于其他共享项,或者在 Cache Storage API 或 IndexedDB 中存储数据和指向媒体的指针。
您可以在示例应用 Fugu Journal 上试用此功能,并在其源代码中查看其 service worker 实现。
您可能会执行的一项常见操作是,在网络连接改善之前一直持有共享资源。Workbox 还支持定期后台同步。
总结
Share Target API 是一种简单的方法,可将您的渐进式 Web 应用深度集成到用户设备中,使其在应用之间共享内容这一关键任务方面与平台专属应用相媲美。但这样做通常需要有服务器来接收请求。通过利用 Workbox 在服务工作线程中直接创建共享目标路由,您的应用不受此限制,从而允许共享目标在应用离线且没有后端的情况下正常运行。
照片提供者:Elaine Casap;来源:Unsplash