我正在开发一个适用于 Firefox 和 Chrome 的浏览器扩展,其功能之一是下载带有图像(webp 或 png)的 zip 文件,我正在使用 JSZip 创建 zip 文件,但它不适用于Firefox,但在 Chrome 上可以。
此代码在内容脚本上运行。
public async getNomiZipAlbumById({ id, type }: GetNomiAlbumProps) {
try {
const NomiInfo = await this.findById(id);
if (!NomiInfo) throw new Error(`Nomi not found (${id})`);
const selfiesInfo = await this.findSelfiesById(NomiInfo.id);
if (selfiesInfo.length === 0) {
throw new Error(
`${Nomi.name} selfies are zero (${NomiInfo.id})`
);
}
const zip = new JSZip();
for (let j = 0; j < selfiesInfo.length; j++) {
try {
const selfie = selfiesInfo[j];
const url = `${env.apiNomiUrl}/nomis/${NomiInfo.id}/selfies/${selfie.id}.${type}`;
const data = await fetch(url);
if (!data.ok)
throw new Error(
`Failed to fetch ${url}: ${data.statusText}`
);
const blob = await data.blob();
console.log("Blob size:", blob.size);
console.log("Blob type:", blob.type);
if (blob.size === 0) {
throw new Error(`Empty blob received from ${url}`);
}
const arrayBuffer = await blob.arrayBuffer(); // Convert to ArrayBuffer
zip.file(`image_${j}_${selfie.id}.${type}`, arrayBuffer);
} catch (error) {
console.log("Error adding img to zip", error);
continue;
}
}
const zipFile = await zip.generateAsync({ type: "blob" });
console.log(zipFile);
if (zipFile.size === 0) {
throw new Error(
`${Nomi.name} zip file is empty (${NomiInfo.id})`
);
}
return zipFile;
} catch (error) {
console.log("Error generating zip", error);
return null;
}
}
错误:无法读取“image_0_d4d66a60a6563b7ffcec5ed6053bdecfd219ec1c2837ec0d0e932aed49aec696.webp”的数据。它是受支持的 JavaScript 类型(String、Blob、ArrayBuffer 等)吗?
我尝试过只传递 blob,将 blob 作为承诺,将数组缓冲区作为承诺,以及我从 chatGPT 获得的代码
const reader = new FileReader();
reader.onload = function (event) {
const arrayBuffer = event.target?.result;
if (arrayBuffer) {
zip.file(
`image_${j}_${selfie.id}.${type}`,
arrayBuffer
);
}
};
reader.readAsArrayBuffer(blob);
我修复了将图像保存为 base64 而不是 blob 或数组缓冲区
const blob = await data.blob();
const base64 = await controller.util.blobToBase64(blob);
zip.file(
`image_${j}_${selfie.id}.${type}`,
base64.split(",")[1],
{
base64: true,
}
);