Exploring the hidden contents within the zip file

I have been exploring methods for reading 'zip' files.

Two libraries that I have used are zip.js and JSzip.

I have successfully viewed the contents of the zip file.

However, here lies the challenge:

My goal is to identify specific file types within the 'zip' files. The issue arises when there is a nested zip file inside the main one, as the contents remain inaccessible without a file object required by the methods.

https://i.sstatic.net/v9k6y.png

It is evident from the screenshot that the files are not in the correct object file type format. Consequently, I am unable to execute the method for "FreeIcons - Copia.zip."

Now, the question becomes how can I recursively (or iteratively) navigate through each zip file contained within the user-entered files.

In the case of using the zip.js library, this code snippet showcases the approach:

const reader = new zip.ZipReader(new zip.BlobReader(file)); //file => User entered file object
const entries = await reader.getEntries();

Answer №1

Utilizing zip.js offers the possibility to utilize the function below, which takes a ZipReader instance as input and retrieves all entries recursively.

async function getAllEntries(zipReader, options) {
  let entries = await zipReader.getEntries(options);
  entries = await Promise.all(entries.map(async entry => {
    if (entry.filename.toLowerCase().endsWith(".zip")) {
      const innerZipReader = new zip.ZipReader(new zip.BlobReader(await entry.getData(new zip.BlobWriter())));
      return getAllEntries(innerZipReader, options);
    } else {
      return entry;
    }
  }));
  return entries.flat();
}

Below is a sample code demonstrating how to use this function.

/* global zip, Blob */

"use strict";

const TEXT_CONTENT = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod...";
const TEXT_CONTENT_BLOB = new Blob([TEXT_CONTENT], { type: "text/plain" });

test().catch(error => console.error(error));

async function test() {  
  // creates a zip file containing 3 text files
  let zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"));  
  await zipWriter.add("lorem1.txt", new zip.BlobReader(TEXT_CONTENT_BLOB));  
  await zipWriter.add("lorem2.txt", new zip.BlobReader(TEXT_CONTENT_BLOB));
  await zipWriter.add("lorem3.txt", new zip.BlobReader(TEXT_CONTENT_BLOB));  
  const loremZip1 = await zipWriter.close();  

  // creates a zip file containing 2 text files
  zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"));
  await zipWriter.add("another_lorem1.txt", new zip.BlobReader(TEXT_CONTENT_BLOB));
  await zipWriter.add("another_lorem2.txt", new zip.BlobReader(TEXT_CONTENT_BLOB));
  const loremZip2 = await zipWriter.close();

  // creates a zip file containing the first zip file and a text file
  zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"));
  await zipWriter.add("lorem1.zip", new zip.BlobReader(loremZip1));
  await zipWriter.add("another_lorem3.txt", new zip.BlobReader(TEXT_CONTENT_BLOB));
  const loremZip3 = await zipWriter.close();

  // creates a zip file containing the 2 previous files and a text file
  zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"));
  await zipWriter.add("lorem3.zip", new zip.BlobReader(loremZip3));
  await zipWriter.add("lorem2.zip", new zip.BlobReader(loremZip2));
  await zipWriter.add("yet_another_lorem.txt", new zip.BlobReader(TEXT_CONTENT_BLOB));  
  const compressedFile = await zipWriter.close();

  // retrieve all entries recursively
  const entries = await getAllEntries(new zip.ZipReader(new zip.BlobReader(compressedFile)));
  document.body.innerHTML = entries.map(entry => entry.filename).join("<br>");
}

async function getAllEntries(zipReader, options) {
  let entries = await zipReader.getEntries(options);
  entries = await Promise.all(entries.map(async entry => {
    if (entry.filename.toLowerCase().endsWith(".zip")) {
      const innerZipReader = new zip.ZipReader(new zip.BlobReader(await entry.getData(new zip.BlobWriter())));
      return getAllEntries(innerZipReader, options);
    } else {
      return entry;
    }
  }));
  return entries.flat();
}

You can execute this code here: https://plnkr.co/edit/yhSnJFmsKyq6m4uH

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Looping through a series of URLs in AngularJS and performing an $

Currently, I am facing an issue while using angular.js with a C# web service. My requirement is to increment ng-repeat item by item in order to display updated data to the user. To achieve this, I attempted to utilize $http.get within a loop to refresh t ...

Copy and paste the code from your clipboard into various input fields

I have been searching for a Vanilla JavaScript solution to copy and paste code into multiple input fields. Although I have found solutions on the internet, they are all jQuery-based. Here is an example of such a jQuery solution <input type="text" maxl ...

Each time the page is reloaded, the Ajax call is triggered, resulting in duplicated

When I visit my homepage, one of the components on the page looks like this: import React, {Component} from 'react'; class BlogPostsWidget extends Component { render() { $.ajax({ type: "GET", url: 'https://example.com/wp- ...

Incorporating geocoding functionality in an asp.net mvc project and looking to efficiently transfer latitude and longitude data from JavaScript to a controller function

UPDATED. Following your suggestions, I implemented the function as shown below: [HttpPost] public ActionResult populate_place(string lati, string longi) { list_placesModels list_place = new list_placesModels(); list_place.Latitude = lati; li ...

Guide on transferring data from a component to App.vue in Vue 3, even with a router-view in the mix

I have the following layout: src components Footer.vue views Page.vue App.vue I want to access the 'message' vari ...

Using JavaScript's `Map` function instead of a traditional `for`

My dataset consists of a csv file containing 5000 rows, with each row having thirty fields representing measurements of different chemical elements. I aim to parse and visualize this data using D3js. Upon reading the file, I obtain an array of length 5000 ...

Is there a way for me to collaborate on a footer control with a different website?

Is it possible to seamlessly incorporate a footer from one website into another? Ideally, I want the footer HTML (and styles) to be dynamically inserted into different web pages. The common workaround is using an iframe, but this causes navigation issues ...

Simultaneously iterate through two recursive arrays (each containing another array) using JavaScript

I have two sets of arrays composed of objects, each of which may contain another set of arrays. How can I efficiently iterate through both arrays and compare them? interface items { name:string; subItems:items[]; value:string; } Array A=['parent1&ap ...

Guidance on incorporating a function as a prop in React using TypeScript

I'm currently learning TypeScript with React and ran into an issue. I attempted to pass a function as a property from my App component to a child component named DataForm. However, I encountered the following error: Type '(f: any) => any&ap ...

Looking to disable the back button in the browser using next.js?

How can I prevent the browser's back button from working in next.js? // not blocked... Router.onRouteChangeStart = (url) => { return false; }; Does anyone know of a way to disable the browser's back button in next.js? ...

React Native Child Component State Update Issue

In my code, there is a Child component that triggers a function in the Parent component. However, when the function is triggered, an error related to the setState method is thrown. Issue with Promise Rejection (id: 0): The '_this12.setState' i ...

Supertest and Jest do not allow for sending JSON payloads between requests

Below is the test function I have written: describe("Test to Create a Problem", () => { describe("Create a problem with valid input data", () => { it("Should successfully create a problem", async () => { const ProblemData = { ...

Different ways to change the value of a variable in an isolated scope using another directive

Utilizing a directive with two modes, edit and preview, multiple times in my codebase. function () { return { restrict: "E", scope : { model : '=' }, [...] controller : function($scope, $el ...

Encountering an ExpressionChangedAfterItHasBeenCheckedError in Angular 6 when selecting an option from a dropdown menu

How can we fix the error mentioned below through code changes? Situation An input dropdown UI is safeguarded against unintentional value changes by a modal. However, triggering an event (such as click or focus) on the dropdown leads to the ExpressionChan ...

The full screen menu is exclusively displayed in the navigation bar

My HTML and CSS code is causing an issue where the full-screen menu only appears in the nav bar. This problem seems to be specific to Safari. To solve the issue, I need to remove the following code: .nav { position: fixed; } However, I still ...

What is the best way to transfer properties to a different component using the onClick event triggered by an element generated within the map function?

I am currently working on an application using react to retrieve data from a mongodb database. Within one of the components, called Gallery, I have integrated a map function to display a list of items. My goal is to implement an onClick event for each elem ...

Using a jquery function within a Laravel view

I am trying to retrieve a selected item from a dropdown menu using jQuery and then redirect it to a controller function. This function will return some data to be displayed based on the selected item. I could really use some assistance with this. Here is m ...

The redesigned pie chart animations in d3 are experiencing glitches

Previously, I had a pie chart with fantastic animations. You can view it here: https://jsfiddle.net/tk5xog0g/29/ I tried to rebuild the chart and improve it based on my needs, but the animations no longer work as intended. I suspect this might be due to ...

The logout feature might refresh the page, yet the user remains logged in

Currently, I am enrolled in a course on Udemy where the instructor is utilizing Angular 2. My task involves building the app using the latest version of Angular. The issue that I am facing pertains to the logout functionality. After successfully logging ou ...

Issue with e2e.js file format in Cypress Support

I am trying to save Cypress screenshots into a report using a support file as recommended in the documentation. However, I keep encountering an error: Your supportFile is missing or invalid: support/e2e.js The supportFile must be a .js, .ts, .coffee file ...