Have a look at zip.js documentation and demo page. Also notice the use of JavaScript filesystem API to read/write files and create temporary files.
If the zip file contains multiple entries, you could read the zip file entries and display a table of links to download each individual file as in the demo above.
If you look the source of the demo page, you see the following code (code pasted from Github demo page for zip.js) (I've added comments to explain):
function(obj) {
//Request fileSystemObject from JavaScript library for native support
var requestFileSystem = obj.webkitRequestFileSystem || obj.mozRequestFileSystem || obj.requestFileSystem;
function onerror(message) {
alert(message);
}
//Create a data model to handle unzipping and downloading
var model = (function() {
var URL = obj.webkitURL || obj.mozURL || obj.URL;
return {
getEntries : function(file, onend) {
zip.createReader(new zip.BlobReader(file), function(zipReader) {
zipReader.getEntries(onend);
}, onerror);
},
getEntryFile : function(entry, creationMethod, onend, onprogress) {
var writer, zipFileEntry;
function getData() {
entry.getData(writer, function(blob) {
var blobURL = creationMethod == "Blob" ? URL.createObjectURL(blob) : zipFileEntry.toURL();
onend(blobURL);
}, onprogress);
}
//Write the entire file as a blob
if (creationMethod == "Blob") {
writer = new zip.BlobWriter();
getData();
} else {
//Use the file writer to write the file clicked by user.
createTempFile(function(fileEntry) {
zipFileEntry = fileEntry;
writer = new zip.FileWriter(zipFileEntry);
getData();
});
}
}
};
})();
(function() {
var fileInput = document.getElementById("file-input");
var unzipProgress = document.createElement("progress");
var fileList = document.getElementById("file-list");
var creationMethodInput = document.getElementById("creation-method-input");
//The download function here gets called when the user clicks on the download link for each file.
function download(entry, li, a) {
model.getEntryFile(entry, creationMethodInput.value, function(blobURL) {
var clickEvent = document.createEvent("MouseEvent");
if (unzipProgress.parentNode)
unzipProgress.parentNode.removeChild(unzipProgress);
unzipProgress.value = 0;
unzipProgress.max = 0;
clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.href = blobURL;
a.download = entry.filename;
a.dispatchEvent(clickEvent);
}, function(current, total) {
unzipProgress.value = current;
unzipProgress.max = total;
li.appendChild(unzipProgress);
});
}
if (typeof requestFileSystem == "undefined")
creationMethodInput.options.length = 1;
fileInput.addEventListener('change', function() {
fileInput.disabled = true;
//Create a list of anchor links to display to download files on the web page
model.getEntries(fileInput.files[0], function(entries) {
fileList.innerHTML = "";
entries.forEach(function(entry) {
var li = document.createElement("li");
var a = document.createElement("a");
a.textContent = entry.filename;
a.href = "#";
//Click event handler
a.addEventListener("click", function(event) {
if (!a.download) {
download(entry, li, a);
event.preventDefault();
return false;
}
}, false);
li.appendChild(a);
fileList.appendChild(li);
});
});
}, false);
})();
})(this);