SoFunction
Updated on 2025-04-09

Share methods and techniques for decompressing zip in front-end of JS

Sometimes you need to obtain a certainzipThe file contents in the compressed package are displayed to the front end,zipWhen the package is not that large (several MB, more than ten MB or even dozens of MB) and does not involve compressed package decryption, you can consider a pure front-end solution.

Decompress zip using Jszip in the front end

Installation dependencies:npm i jszip

askzipFile and convert toBlob:

const blob = await fetch(url).then((res) => ());

usejszipUnzipBlob:

const zip = new JSZip()
const zipData = await (zipBlob)

You will get a containingfilesList of datazipData, thisfilesIt is the file list in the compressed package. The processing at this time is interesting, let’s talk about it slowly.

How to get more than one file in your compressed package

Based on the previous step, we got itfilesFile list. At this time, if there are many files in our compressed package, how can we get all of them? We need to recurse this list:

async function extractNestedZip(zipBlob: Blob) {
  const zip = new JSZip()
  const zipData = await (zipBlob)

  const extractedFiles: { name: string, data: unkown }[] = []

  // traverse all files in the ZIP file  for (const [name, file] of ()) {
    ({name, file})
  }

  return extractedFiles
}

But things are often not that simple. For example, what should I do if there is a compressed package in the compressed package?

How to deal with nested compression modification

ImprovementextractNestedZipmethod:

async function extractNestedZip(zipBlob: Blob) {
  const zip = new JSZip()
  const zipData = await (zipBlob)

  const extractedFiles: { name: string, data: unkown }[] = []

  // traverse all files in the ZIP file  for (const [name, file] of ()) {
    if (('.zip') { // If it is a nested compressed package, continue to decompress      const nestedZipBlob = await ('blob')
      const nestedFiles = await extractNestedZip(nestedZipBlob)
      (...nestedFiles)
    } else {
      ({name, file})
    }
  }

  return extractedFiles
}

We've solved the nesting problem now. What should I do if there are folders in the compressed package? If you try it, you will find that if it is a folder,filesThe corresponding data in  is empty, so we should filter this situation:

Folders in the compressed package need to be filtered

async function extractNestedZip(zipBlob: Blob) {
  const zip = new JSZip()
  const zipData = await (zipBlob)

  const extractedFiles: { name: string, data: unkown }[] = []

  // traverse all files in the ZIP file  for (const [name, file] of ()) {
    if (('.zip') { // If it is a nested compressed package, continue to decompress      const nestedZipBlob = await ('blob')
      const nestedFiles = await extractNestedZip(nestedZipBlob)
      (...nestedFiles)
    } else if (!('/')) { // We can determine whether this item is a folder by judging whether the file name ends with /      ({name, file})
    }
  }

  return extractedFiles
}

Now I read it, it seems that everything is fine, but how do we read the final file?

Text files and binary files must be processed separately

If the zip package contains only text-class files, for example.json,.logIt can be used simply('text')to get the file content, but if it contains.mp3,.pngWe need to pay attention to these situations:

async function extractNestedZip(zipBlob: Blob) {
  const zip = new JSZip()
  const zipData = await (zipBlob)

  const extractedFiles: { name: string, data: string | Blob }[] = []

  // traverse all files in the ZIP file  for (const [name, file] of ()) {
    if (('.zip')) {
      // If the file is a nested ZIP file, recursively decompress      const nestedZipBlob = await ('blob')
      const nestedFiles: { name: string, data: string | Blob }[]  = await extractNestedZip(nestedZipBlob)
      (...nestedFiles)
    }
    else {
      // If the file is not a ZIP file, then process      if (('.jpeg') || ('.png') || ('.mp3') || ('.mp4')) {
        const blob = await ('blob')
        ({ name, data: blob })
      }
      else if (!('/')) { // Filter out folders        const fileData = await ('text')
        ({ name, data: fileData })
      }
    }
  }

  return extractedFiles
}

We have given some examples here, which is to determine what ends with the file name. If it is a common media format, it will be converted toBlob, otherwise it will be converted to a string. This solution can handle the problem of different formats in the compressed package, and we finally got onenameIt indicates the file name in the compressed package.dataIt is a list of corresponding file contents.

Summarize

It is rare to need front-end scenario decompression and compression packages in business, but if there are such scenarios, we can use the help ofjszipCome and do it. What I share this time is mainly about how to get all the contents of the compressed package after getting the file. If you have any other questions, please feel free to communicate in the comment area.

The above is the detailed content of the methods and techniques for decompressing zip on the front-end of JS. For more information about decompressing zip on the front-end of JS, please pay attention to my other related articles!