data:;base64,aGVsbG8=image.png, background.pngstyle.css,
								properties.css
							script.jsproject/ folderProject structure
project/index.html
project/script.js
project/style.css
project/properties.css
project/image.png
project/background.png
							
					Project structure
project/index.html
project/script.js
project/style.css
project/properties.css
project/image.png
project/background.png
							
					Project structure
project/index.html
project/script.js
project/style.css
project/properties.css
project/image.png
project/background.png
							
					Project structure
project/index.html
project/script.js
project/style.css
project/properties.css
project/image.png
project/background.png
							
					DEFLATE format since version 2.0 (1993)
							AES encryption since version 5.2 (2003).ODT, .DOCX,
								...).JAR).APK and Archives iOS .IPA)
							.CRX and .XPI)CompressionStream APIExample of ZIP file creation
					import { ZipWriter, Uint8ArrayWriter } from "@zip-js/zip-js"
const zipDataWriter = new Uint8ArrayWriter()
const zipWriter = new ZipWriter(zipDataWriter)
for await (const { name } of readDirectory(inputFolder)) {
	const readableStream = await readFileStream(name)
	await zipWriter.add(name, readableStream)
}
await zipWriter.close()
const zipData = zipDataWriter.getData() // Uint8Array
console.log("zip file data:", zipData)
				
			Creation of the ZIP file
index.html
index.js
lib/utils-zip.js
							
					Creation of the ZIP file
index.html
index.js
lib/utils-zip.js
							
					Creation of the ZIP file
index.html
index.js
lib/utils-zip.js
							
					Creation of the ZIP file
index.html
index.js
lib/utils-zip.js
							
					Example of reading a ZIP file
					import { ZipReader, BlobReader, BlobWriter } from "@zip-js/zip-js"
const zipReader = new ZipReader(new BlobReader(blob))
const entries = await zipReader.getEntries()
for (const entry of entries) {
	const blob = await entry.getData(new BlobWriter())
	console.log("file:", entry.filename, "blob:", blob)
}
await zipReader.close()
			
			Reading the ZIP file
index.html
index.js
							
					Reading the ZIP file
index.html
index.js
							
					Reading the ZIP file
<!----> and end of HTML contentSelf-extracting HTML file template
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Please wait...</title>
		<script><!-- Content of assets/zip.min.js --></script>
	</head>
	<body>
		<p>Please wait...</p>
		<script><!-- Content of assets/main.js --></script>
  </body>
</html>Self-extracting HTML file template
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Please wait...</title> <script><!-- Content of assets/zip.min.js --></script> </head> <body> <p>Please wait...</p> <!--ZIP data--> <script><!-- Content of assets/main.js --></script> </body> </html>
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					2/4 - Displaying the index.html page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					3/4 - Displaying the full page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Inactive JavaScript code ⚠️
4/4 - Scripts support
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Reading the page from the file system ⚠️
await fetch("")Node#textContent (in UTF-16)windows-1252) versus
								multiple bytes (e.g. UTF-8)
							U+FFFD replacement characters for
								characters whose code is 0 or invalid (depending on encoding) \n of the characters:
								\r\r\n
									ASCII 7-bit tableHexadecimal display of ZIP data read as text
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					
					UTF-8: 
				
					windows-1252: 
				
Comparison of the impact of different 1-byte encodings
U+FFFD (first
								column)Comparison of the impact of different 1-byte encodings
Changes in the HTML template
UTF-8 encoding with windows-1252\r\r\n
							<script> tag
					Self-extracting HTML file template (before)
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Please wait...</title>
		<script><!-- Content of assets/zip.min.js --></script>
	</head>
	<body>
		<p>Please wait...</p><!--
		  ZIP data 
		-->
		<script><!-- Content of assets/main.js --></script>
  </body>
</html>Self-extracting HTML file template (after)
<!DOCTYPE html>
<html>
	<head>
		<meta charset="windows-1252">
		<title>Please wait...</title>
		<script><!-- Content of assets/zip.min.js --></script>
	</head>
	<body>
		<p>Please wait...</p><!--
		  ZIP data 
		-->
		<script><!-- Content of assets/main.js --></script>
  </body>
</html>Self-extracting HTML file template (after)
<!DOCTYPE html> <html> <head> <meta charset="windows-1252"> <title>Please wait...</title> <script><!-- Content of assets/zip.min.js --></script> </head> <body> <p>Please wait...</p><!-- ZIP data --> <script type="application/json">Consolidation data</script> <script><!-- Content of assets/main.js --></script> </body> </html>
Support for consolidation data in the HTML template
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Support for consolidation data in the HTML template
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Adding consolidation data to the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Adding consolidation data to the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Adding consolidation data to the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Bypassing the call to await fetch("")
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Bypassing the call to await fetch("")
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					Page resources are decoded in windows-1252 ⚠️
Correction of MIME type issues in external resources
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
							
					DEFLATE)IHDR, IDAT,
								IEND, tEXt ...
							CRC32) computed from all the chunk
								data89 50 4E 47  0D 0A 1A 0AIHDR chunk for the header (13 bytes)
								00 00 00 0D  49 48 44 52  ...IDAT chunk(s) for the data
							IEND chunk for the trailer (12 bytes)
								00 00 00 00  49 45 4E 44  AE 42 60 82tEXt chunk to store text or binary data
						xx xx xx xx  74 45 58 74  ...Minimal PNG file structure
| Data type | Data in hexadecimal | Mandatory | Length (bytes) | |
|---|---|---|---|---|
| PNG signature | 89 50 4E 47  0D 0A 1A 0A | ✓ | 8 | |
| Header chunk | IHDR | 00 00 00 0D  49 48 44 52  ... | ✓ | 13 | 
| ... | ||||
| Data chunk | IDAT | xx xx xx xx  49 44 41 54  ... | 12 + n | |
| ... | ||||
| Trailer chunk | IEND | 00 00 00 00  49 45 4E 44  AE 42 60 82 | ✓ | 12 | 
<!--
							--> and end of HTML content
							PNG file structure (before)
| Data type | Data in hexadecimal | Mandatory | Length (bytes) | |
|---|---|---|---|---|
| PNG signature | 89 50 4E 47  0D 0A 1A 0A | ✓ | 8 | |
| Header chunk | IHDR | 00 00 00 0D  49 48 44 52  ... | ✓ | 13 | 
| ... | ||||
| Data chunk | IDAT | xx xx xx xx  49 44 41 54  ... | 12 + n | |
| ... | ||||
| Trailer chunk | IEND | 00 00 00 00  49 45 4E 44  AE 42 60 82 | ✓ | 12 | 
PNG file structure (after)
| Data type | Data in hexadecimal | Mandatory | Length (bytes) | |
|---|---|---|---|---|
| PNG signature | 89 50 4E 47  0D 0A 1A 0A | ✓ | 8 | |
| Header chunk | IHDR | 00 00 00 0D  49 48 44 52  ... | ✓ | 13 | 
| Text chunk | tEXt | xx xx xx xx  74 45 58 74  ... | 12 + n | |
| ... | ||||
| Data chunk | IDAT | xx xx xx xx  49 44 41 54  ... | 12 + n | |
| ... | ||||
| Text chunk | tEXt | xx xx xx xx  74 45 58 74  ... | 12 + n | |
| Trailer chunk | IEND | 00 00 00 00  49 45 4E 44  AE 42 60 82 | ✓ | 12 | 
Self-extracting HTML file template (before)
<!DOCTYPE html> <html> <head> <meta charset="windows-1252"> ... </head> <body> <p>Please wait...</p><!--ZIP data --><script type="application/json"> Consolidation data </script> <script><!-- Content of assets/main.js --></script> </body> </html>
Self-extracting HTML file template (after)
<!DOCTYPE html> <html> <head> <meta charset="windows-1252"> ... </head> <body> <p>Please wait...</p><!--IDAT chunk(s)--><!-- ZIP data --><script type="application/json"> Consolidation data </script> <script><!-- Content of assets/main.js --></script> </body> </html>
Self-extracting HTML file template (after)
PNG signature + IHDR chunk (21 bytes)<!DOCTYPE html> <html> <head> <meta charset="windows-1252"> ... </head> <body> <p>Please wait...</p><!--IDAT chunk(s)--><!-- ZIP data --><script type="application/json"> Consolidation data </script> <script><!-- Content of assets/main.js --></script> </body> </html>IEND chunk (12 bytes)
Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
							
					Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
							
					Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
							
					Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
							
					Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
							
					Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
							
					Text nodes induced by the PNG format are visible ⚠️
Removal of text nodes induced by PNG format
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
							
					The page is rendered in quirks mode ⚠️
Correction of HTML page rendering mode and script loading
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
							
					The main image is stored twice in the file 🤔
Reuse of the image in the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
project/index.html
							
					Reuse of the image in the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
project/index.html
							
					Reuse of the image in the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
project/index.html
							
					--> in ZIP or PNG binary dataString#replaceAll() to replace paths in text files
								instead of relying on parsing<meta> tag containing the Content
									Security Policy (CSP)
							Questions? 🤔, Feedback? 📝
