是否可以使用Background Fetch Api来上传文件..?

问题描述 投票:0回答:1

我正在努力在我的 Vue 项目中实现后台获取 API,以支持将文件上传到 S3 存储桶。目标是即使用户关闭屏幕也允许上传过程继续,这对于移动 Web 应用程序特别有用。此功能可确保文件上传在后台成功完成,从而提供不间断的无缝用户体验。

这是我的示例代码: 在 service-worker.js 中:

self.addEventListener("install", (event) => {
  event.waitUntil(console.log("Service worker installing"));
});

self.addEventListener("activate", (event) => {
  console.log("Service Worker activating.");
});

self.addEventListener("fetch", (event) => {
  console.log("This is fetch");
});

self.addEventListener("backgroundfetchsuccess", async (event) => {
  const bgFetch = event.registration;
  const records = await bgFetch.matchAll();
  for (const record of records) {
    const response = await record.responseReady;
    if (!response.ok) {
      throw new Error(`Error response status: ${response.status}`);
    }
    console.log(`File uploaded successfully: ${response.status}`);
  }
  console.log("Background fetch success:", event);
});

self.addEventListener("backgroundfetchfail", async (event) => {
  console.log("Background fetch fail:", event);
});

self.addEventListener("backgroundfetchabort", async (event) => {
  console.log("Background fetch abort:", event);
});

这是我的上传功能:

const uploadFile = async () => {
  if (!selectedFile.value) {
    message.value = "No file selected";
    return;
  }

  message.value = "Generating presigned URL...";
  let presignedUrl;

  try {
    const s3Client = new S3Client({
      region: s3Config.region,
      credentials: {
        accessKeyId: s3Config.accessKeyId,
        secretAccessKey: s3Config.secretAccessKey,
      },
    });

    const command = new PutObjectCommand({
      Bucket: s3Config.bucketName,
      Key: selectedFile.value.name,
      ContentType: selectedFile.value.type,
    });

    presignedUrl = await getSignedUrl(s3Client, command, { expiresIn: 3600 });
  } catch (error) {
    message.value = `Error generating presigned URL: ${error.message}`;
    return;
  }

  message.value = "Uploading...";

  if ("BackgroundFetchManager" in self) {
    try {
      const swReg = await navigator.serviceWorker.ready;
      console.log("Service Worker ready:", swReg);

      const bgFetch = await swReg.backgroundFetch.fetch(
        "upload-file-abc",
        [
          new Request(presignedUrl, {
            method: "PUT",
            body: selectedFile.value,
            headers: { "Content-Type": selectedFile.value.type },
          }),
        ],
        {
          title: "File Upload",
          downloadTotal: selectedFile.value.size,
        }
      );

      bgFetch.addEventListener("progress", (event) => {
        if (!event.uploadTotal || !event.uploaded) return;
        const percent = Math.round((event.uploaded / event.uploadTotal) * 100);
        console.log(`Upload progress: ${percent}%`);
      });

    } catch (error) {
      message.value = `Error uploading file: ${error.message}`;
    }
  } else {
    message.value = "Background Fetch API not supported";
  }
};

当我尝试上传文件时,它会触发:后台获取失败事件 我是不是错过了什么..?

amazon-s3 file-upload vuejs3 service-worker background-fetch
1个回答
0
投票

我成功实现了 POST API 来上传文件,对于最大 10MB 的文件效果很好。但是,我在尝试上传较大文件(超过 10MB)时遇到问题。

我尝试使用PUT方法上传文件,但不幸的是,没有成功。我怀疑该 API 不处理 PUT 请求。

如果有人有此问题的经验或知道解决方案,请分享您的想法。如果您能帮助解决这个问题,我将不胜感激。

   const request = new Request(url, {
    method: "POST",
    body: formData,
  });
    const reg = await navigator.serviceWorker.ready;
    console.log("Reg", reg);
    startTime.value = Date.now();
    console.log("Start time", startTime.value);
    const bgFetchReg = await reg.backgroundFetch.fetch("my-upload", [request], {
      uploadTotal: formData.size,
      downloadTotal: 0,
      title: "Uploading file",
      icons: [{ src: "./movie.png", sizes: "192x192", type: "image/png" }],
    });

    bgFetchReg.addEventListener("progress", () => {
      console.log("Upload progressing ");
      const uploaded = bgFetchReg.uploaded;
      const uploadedMB = uploaded / (1024 * 1024);
      console.log(`Uploaded size: ${uploadedMB.toFixed(2)} MB`);

      const uploadTotal = bgFetchReg.uploadTotal;
      const uploadTotalMB = uploadTotal / (1024 * 1024);
      console.log(`Total size to upload: ${uploadTotalMB.toFixed(2)} MB`);

      const progress = (uploaded / uploadTotal) * 100;
      console.log(`Upload progress: ${progress.toFixed(2)}%`);
    });

© www.soinside.com 2019 - 2024. All rights reserved.