typescriptblobfirefox-addonvitejszip

Creating zip file from image blobs on a content script of firefox extension


I'm developing a browser extension that works on Firefox and Chrome, one of its features is to download a zip file with images (webp or png) and I'm using JSZip to create the zip file, but it does not works on Firefox, but it does on Chrome.

This code is running on a content script.

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;
}

}

Error: Can't read the data of 'image_0_d4d66a60a6563b7ffcec5ed6053bdecfd219ec1c2837ec0d0e932aed49aec696.webp'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?

Firefox logs

I have tried passing just the blob, the blob as a promise, array buffer as a promise and this code I got from 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);

Solution

  • I fixed saving the image as base64 instead of blob or array buffer

    const blob = await data.blob();
    
    const base64 = await controller.util.blobToBase64(blob);
    
    zip.file(
        `image_${j}_${selfie.id}.${type}`,
        base64.split(",")[1],
        {
            base64: true,
        }
    );