[JavaScript][Unarchiver.js] Retrieving Zip/RAR Contents from a Server

This article can be read in about 7 minutes.
PR

The purpose 

Using JavaScript, I will retrieve the contents of Zip/RAR files on a server without saving the files locally.

The general flow is as follows: (Files will not be saved locally)

The library used also appears to support tar, gz, xz, and bz2 in addition to zip/rar, but I have not confirmed their operation.

  • Fetch Zip/RAR file from server
  • Get files from within the Zip/RAR file
  • (Display image files)

I am using NodeJS. (It’s not strictly necessary as I’m using it for a testing environment.)

Large RAR files cannot be read. This is a limitation of the libunrar library being used. While it might be environment-dependent, in my environment, files around 300MB start to become problematic. Split RAR files are not supported.

This is because Unarchiver.js does not support them. libunrar does support them, so it would be possible to add support by modifying Unarchiver.js.

PR

Install environment

Download unarchiver.zip from the “Download” section at the top of the following page.

Unarchiver.js
Unarchiver.js

Extract the downloaded files to any folder within your project.

(Here, I extracted them to src/unarchiver.)

PR

Implementation

Load Script

Add the following line to the HTML you are using to load the script.

It needs to be loaded before any JS that uses unarchiver. (Please change the src path to match your environment.

If you are not using Node.js, the path will not be relative to the root.)

  <script src="/src/unarchiver/unarchiver.min.js"></script>

It is correct not to specify the type. If you specify module or similar, it will not work.

Downloading Zip/RAR and Retrieving the Initial File

The implementation is as follows.

It downloads and decompresses test.rar.

The first file contained within the Zip file will be saved in file_data in File format.

The File format can be used as a Blob.

await Unarchiver.load();

let url = 'test.rar';
const data = await fetch(url);
const blob = await data.blob();
const file = new File([blob], url.split('/').pop(), { type: blob.type });
const archive = await Unarchiver.open(file);
const entry = archive.entries[0]
const file_data = await entry.read()

Use file(image)

If the retrieved data is a JPEG image, you can display the acquired File using URL.createObjectURL.

(An <img> tag with the ID downloaded is prepared in the HTML for display.)

Although the File object is acquired when specifying the argument for createObjectURL rather than using file_data from above, the result is the same.

const entry = archive.entries[0]
//const file_data = await entry.read()
if (entry.is_file && (entry.name.endsWith(".jpg") || entry.name.endsWith(".jpeg"))) {
  const img = document.getElementById("downloaded");
  img.src = URL.createObjectURL(await entry.read());
}
PR

Other memo

Retrieving the Second and other Files

archive.entries is an array of file information. You can access the second file with archive.entries[1].

about sub-folder

Please note that the behavior may differ between Zip and RAR.

zip case

Files contained in subfolders are also included in archive.entries.

Folder information is not included in zipReader.getEntries(). (The filename of each file includes the folder path.)

RAR case

Files contained in subfolders are also included in archive.entries.

Folder information is included in zipReader.getEntries(). (The filename of each file includes the folder path.)

Folder entries have .is_file as false and .read returns null.

PR

Result

Using JavaScript, I was able to retrieve the contents of Zip/RAR files from a server without saving them locally, and then display the image files.

PR

Reference

Unarchiver.js
Unarchiver.js

comment

Copied title and URL