【问题标题】:Promise reject on getting formData in WebshareTarget Handler承诺拒绝在 WebshareTarget 处理程序中获取 formData
【发布时间】:2021-04-12 13:25:53
【问题描述】:

当我想在我的应用程序的服务人员中处理 POST 请求时,我经常收到 Promise 拒绝。我喜欢向我的 pwa 发送一个文件,并且在文档中,POST 请求应该有一个我可以使用 .formData() 读取的表单主体,但是这个方法每次都会返回被拒绝的承诺。任何想法我做错了什么?

我的清单:

...
"share_target": {
    "action": "/editor/image",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "title": "name",
      "text": "description",
      "url": "link",
      "files": [
        {
          "name": "file",
          "accept": [
            "*/*"
          ]
        }
      ]
    }
  },
...

我的服务人员:

importScripts("./ngsw-worker.js");

self.addEventListener("fetch", (event) => {
  const url = new URL(event.request.url);

  if (url.origin === location.origin && url.pathname === "/editor/image" && event.request.method === "POST") {
    console.log("Retrieve");
    handleFileShare(event);
  }
});

function handleFileShare(event) {
  let dataPromise;
  try {
    dataPromise = event.request.formData(); // <- FAIL HERE
  } catch (error) {
    console.error(error);
  }

  event.respondWith(Response.redirect("/editor"));
  event.waitUntil(
    (async function () {
      try {
        const client = await self.clients.get(event.resultingClientId);
        const data = await dataPromise;
        const file = data.get("file");
        client.postMessage({ file, action: "load-image" });
      } catch (error) {
        console.log(error);
      }
    })()
  );
}

【问题讨论】:

    标签: javascript angular fetch progressive-web-apps web-share


    【解决方案1】:

    您的 Web 应用程序清单看起来不错,但对于服务工作者,您需要以不同的方式构建代码。这是一个显示所需步骤的 MVP 实现:

    // Service Worker
    self.addEventListener('fetch', (fetchEvent) => {
      /* Start Web Share Target */
      if ((fetchEvent.request.url.endsWith('/editor/image')) &&
          (fetchEvent.request.method === 'POST')) {
        // Call respondWith() early on, so the service worker stays alive.
        return fetchEvent.respondWith((async () => {
          // This function is async.
          const formData = await fetchEvent.request.formData();
          const image = formData.get('image');
          const keys = await caches.keys();
          const mediaCache = await caches
              .open(keys.filter((key) => key.startsWith('media'))[0]);
          await mediaCache.put('shared-image', new Response(image));
          // You need to redirect the user somewhere, since the path
          // /editor/image does not actually exist.
          return Response.redirect('./?share-target', 303);
        })());
      }
      /* End Web Share Target */
    
      /* ... */
    });
    

    那么在客户端你需要检测用户被重定向的情况:

    const restoreImageFromShare = async () => {
      const mediaCache = await getMediaCache();
      const image = await mediaCache.match('shared-image');
      if (image) {
        const blob = await image.blob();
        // Do something with the image and housekeep the cache.
        await mediaCache.delete('shared-image');
      }
    };
    
    // Check for the URL parameter that the service worker sets.
    if (location.search.includes('share-target')) {
      restoreImageFromShare();
    } else {
      drawDefaultImage();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 2017-06-04
      相关资源
      最近更新 更多