我正在努力在我的 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";
}
};
当我尝试上传文件时,它会触发:后台获取失败事件 我是不是错过了什么..?
我成功实现了 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)}%`);
});