如何让您的 PWA 在系统级共享界面中显示在平台专用应用旁边
借助 Web Share Target API,您可以在用户安装渐进式 Web 应用后,在用户的系统级 Sharesheet 中显示该应用。如果您有可接收请求的服务器,这种方法非常有效,但如果没有,则很难实现。
在本文中,我们将使用 Workbox(一组用于向 Web 应用添加离线支持的 JavaScript 库)创建一个完全位于服务工作器内的共享目标网址。这样,静态网站和单页应用就可以作为共享目标,而无需专用服务器端点。
在同一页面上
如果您不熟悉 Web Share Target 的运作方式,请参阅通过 Web Share Target API 接收共享数据,详细了解相关信息。 下面是简要回顾。
实现网站分享目标功能分为两个部分。首先,更新您的网络应用清单,指明您希望应用在安装后成为共享目标。以下示例通过 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"]
}
]
}
}
…
Service Worker 与 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 中试用它,并在其源代码中查看其服务工件实现。
您可以采取的一个常见做法是,在网络连接改善之前保留共享资源。Workbox 还支持定期后台同步。
总结
Share Target API 是一种简单的方式,可将您的渐进式 Web 应用深度集成到用户的设备中,使其在应用间共享内容这一关键任务方面与平台专用应用不相上下。但这样做通常需要有可接收请求的服务器。通过利用 Workbox 直接在服务工件中创建共享目标路由,您的应用便可摆脱此限制,让共享目标在应用离线且没有后端时也能正常运行。
照片由 Elaine Casap 拍摄,选自 Unsplash