使用 Workbox 将 PWA 集成到内置共享界面中

如何在系统级共享界面中让您的 PWA 显示在平台专用应用旁边

借助 Web Share Target API,您可以在安装渐进式 Web 应用后,在用户的系统级分享表单中显示该应用。虽然如果您有可用于接收请求的服务器,这是很好的选择,但如果没有,就很难工作。

在本文中,我们将使用 Workbox(一组用于向 Web 应用添加离线支持的 JavaScript 库)来创建完全位于 Service Worker 内的共享目标网址。这样,无需专用服务器端点,即可将静态网站和单页应用用作共享目标。

Android 手机,其中的“分享方式”抽屉式导航栏处于打开状态。
系统级共享目标选择器,可以选择已安装的名为 Share Target Test 的 PWA。

在同一页面上

如果您不熟悉 Web Share Target 的工作原理,请参阅使用 Web Share Target API 接收共享数据一文,其中详细介绍了该服务。简要回顾一下。

实现网络共享目标功能分为两部分。首先,更新您的 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"]
      }
    ]
  }
}
…

Service Worker 与 Workbox 共享目标

虽然通常由服务器端点处理,但您可以为共享目标做一个小技巧,那就是直接在 Service Worker 中注册一个路由来处理请求。这将使您的应用成为没有后端的共享目标。

为此,您可以在 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 APIIndexedDB 中存储数据和指向媒体的指针。

您可以在示例应用 Fugu Journal 上试用该程序,并在其源代码中查看其 Service Worker 实现。

一种常见的做法是保留共享资源,直到有更好的网络连接为止。Workbox 还支持定期后台同步

总结

Share Target API 是一种将渐进式 Web 应用深度集成到用户设备中的简单方法,使其与平台专用应用相当,可以执行在应用之间共享内容的关键任务。但这样做通常需要有可用的服务器来接收请求。通过利用 Workbox 直接在 Service Worker 中创建共享目标路由,您的应用就不受此限制约束,允许共享目标在离线时和没有后端的情况下运行。

照片由 Elaine Casap 拍摄,来源:Unsplash 用户