Skip to main content
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with: Roman Schlaepfer
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with: Roman Schlaepfer

Warning Users About The Windows Explorer Zip Archive Preview In JavaScript

By
Published in , Comments (1)

In recent years, on a Windows computer, if you double-click on a .zip file - the same way you would navigate into any Folder in the file system - Windows doesn't automatically extract the .zip file contents. Instead, it opens an "Explorer Preview" of the archive, allowing you to view the contents of the archive without actually extracting the embedded files. While this provides some conveniences for the user, it can also break the user experience (UX) in non-intuitive ways. As such, it can sometimes be helpful to alert the user about this non-obvious Explorer experience using JavaScript.

At InVision, I produce a lot of .zip archive files. Which is why I spend so much time writing about the DEFALTE and STORE compression methods, incrementally generating and streaming Zip files on-the-fly, and executing the zip command from a given working directory (using either a proxy shell command or the new directory attribute in Lucee's CFZip tag).

Many of the Zip archive files that I generate are actually "rich reports" that contain an interactive .html file. This HTML file almost always references other files embedded within the archive; which works gang busters, unless you're using the aforementioned Windows Explorer "preview archive" experience. You can tell that you're using this experience if Windows Explorer includes the .zip file extension in the "folder path" and shows you Extraction tools within the toolbar:

Windows Explorer showing preview of Zip archive contents.

As you can see, the .zip file extension is in the Windows Explorer folder path. We haven't unarchived / extracted the file - we've entered into the "archive preview". The problem here is that if you then double-click on the index.html file, Windows extracts that file on-the-fly into a temporary folder:

Windows Explorer extracts the index file on-the-fly into a temporary file location on the computer.

As you can see, while the index.html file opened in the Microsoft Edge browser as one would hope, it's opening from an AppData/Local/Temp/ location - not from the "Downloads" folder in which the Zip archive is actually stored. In many cases, this isn't a problem. However, if the index.html file references other files within the .zip archive, the relative file paths that you have to use in such a case will not work from this AppData/Local/Temp/ location.

So, any linked images, style sheets, and JavaScript files will break (fail to load in the index.html file).

What you end up with is a broken user experience despite the fact that the user double-clicked into the .zip file in the same way that they would have double-clicked into any other type of Folder. Windows has entered an "Uncanny Valley" - it has something that mostly looks and acts like a "Folder", but which leaves much to be desired.

In order to help the user understand why their experience is breaking, we can use JavaScript to put a spotlight on the contextual problem. Thankfully, when Windows Explorer enters this "preview" mode, the .zip file-extension is present in the window.location.href value. Which means, we can look for this value on page-load and then alert() the user that they've entered into a not-quite-a-folder experience:

<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>
		My Archive!
	</title>

	<script type="text/javascript">
		(function() {

			// In Windows Explorer, double-clicking on a ZIP file doesn't extract
			// the .zip file, it just "explores" it. If a file within the ZIP is
			// then opened, any embedded paths are broken. Let's alert the user
			// to this fact if the URL looks liks it contains a ".zip" in it.
			if ( window.location.href.search( new RegExp( "\.zip[\\/]", "i" ) ) >= 0 ) {

				alert(
					"It looks like you are viewing this report from a zipped export file (.zip). " +
					"If some report assets are not displayed correctly, please fully extract " +
					"the zip file and then reopen the html file."
				);

			}

		})();
	</script>

	<!-- .... truncated for demo .... -->
</head>
<body>

	<!-- .... truncated for demo .... -->

</body>
</html>

Here, we're using the Regular Expression pattern:

\.zip[\\/]

... to see if the .zip string is located right before a path-separator (either back-slash or forward-slash). And, if that pattern is found, we open up a native alert() outlining the potential issue.

Now, if the user double-clicks into the .zip file, enters the Windows Explorer archive preview mode, and then double-clicks into the index.html file, they will see the following:

Alerting user to the Windows Explorer zip archive preview experience.

This is not a great user experience (UX); but, it's a whole heck of a lot better than just letting the file open and allowing the embedded resources to break without any explanation. At least with the JavaScript alert, we can hopefully guide the user to a working solution.

Epilogue on Using Data URLs to Embed Resources Within a Single File

One possible work-around for this Windows Explorer archive preview mode problem is to not have any external resources. And, one way to accomplish that is to embed any external resources as Data URLs directly within the index.html file. So, instead of linking to a relative ./files/report.png image file, you can embed the binary image data as a Base64-encoded value right within the <img> tag itself:

<img src="data:image/png;base64,R0lGODlhEAA{ ... really long value ... }" />

To be clear, this works. But, it should only be used when you have a relatively small amount of data to embed. In my experience, including a lot of data as Base64-encoded values quickly leads to massive file sizes and slow load times (depending on where you're loading the file from). It also means that the user cannot easily "explore" the linked files - something that may be a critical part of the user experience. As such, your mileage may vary.

Want to use code from this post? Check out the license.

Reader Comments

15,902 Comments

So, the \.zip[\\/] pattern is not working in all contexts. Some temporary URLs appear to use .zip. in the URL. As such, I've taken to softening the pattern matching to be \.zip\b. This will cover a wider range of URLs and is still unlikely to generate a false-positive match.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel