如何在 PWA 共享目标中离线处理图像?

Dan*_*ton 8 javascript service-worker progressive-web-apps

我可以将我的 Progressive Web App 注册为图像共享目标Chrome Android 76 支持):

"share_target": {
    "action": "/share-target",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "files": [
        {
          "name": "myImage",
          "accept": ["image/jpeg", "image/png"]
        }
      ]
    }
  }
Run Code Online (Sandbox Code Playgroud)

然后,我可以拦截在 Service Worker 中将图像共享到应用程序的尝试:

self.addEventListener('fetch', e => {
  if (e.request.method === 'POST' && e.request.url.endsWith('/share-target')) {
    // todo
  }
})
Run Code Online (Sandbox Code Playgroud)

如何在我的离线 PWA 中显示共享图像?

Jef*_*ick 8

这里有几个不同的步骤。

我在https://web-share-offline.glitch.me/ 上整理了一个工作示例,源在https://glitch.com/edit/#!/web-share-offline

确保您的网络应用离线工作

这是一个先决条件,我通过生成一个 Service Worker 来实现它,该 Service Worker 将使用Workbox预缓存我的 HTML、JS 和 CSS 。

加载主页时运行的 JS 使用缓存存储 API 读取已缓存的图像 URL 列表,以<img>在页面上创建与每个元素对应的元素。

创建将缓存图像的共享目标处理程序

我也为此使用了 Workbox,但它涉及更多。要点是:

  • 确保拦截POST对配置的共享目标 URL 的请求。
  • 读取共享图像的主体并使用缓存存储 API 将它们写入本地缓存取决于您。
  • 将共享图像保存到缓存后,最好POST使用HTTP 303重定向响应来响应,以便浏览器显示 Web 应用程序的实际主页。

这是我用来处理此问题的 Workbox 配置代码:

const shareTargetHandler = async ({event}) => {
  const formData = await event.request.formData();
  const cache = await caches.open('images');

  await cache.put(
      // TODO: Come up with a more meaningful cache key.
      `/images/${Date.now()}`,
      // TODO: Get more meaningful metadata and use it
      // to construct the response.
      new Response(formData.get('image'))
  );

  // After the POST succeeds, redirect to the main page.
  return Response.redirect('/', 303);
};

module.exports = {
  // ... other Workbox config ...
  runtimeCaching: [{
    // Create a 'fake' route to handle the incoming POST.
    urlPattern: '/share-target',
    method: 'POST',
    handler: shareTargetHandler,
  }, {
    // Create a route to serve the cached images.
    urlPattern: new RegExp('/images/\\d+'),
    handler: 'CacheOnly',
    options: {
      cacheName: 'images',
    },
  }],
};
Run Code Online (Sandbox Code Playgroud)