nickvans
nickvans

Reputation: 938

Archive contents are corrupted using jszip

I'm doing some local development of a web app and need to create a zip archive out of some files client side. I have a very simple test page with a button and download link. Clicking the button generates a zip file using the jszip library that includes a png image loaded using an XMLHttpRequest. When you click the download link an archive is downloaded and it contains a png image file, but the png image is corrupted. Windows tells me:

"WinZip Viewer was unable to display an image because the image file is missing or invalid; image skipped."

I tried following "regular"'s solution of fixing the upper byte to 0xff, but I get the same result. (This is my GetZip2() function.)

Can anyone offer an idea as to why the zip contents are getting corrupted?

Thanks in advance

HTML code:

<html>  
    <head>  
        <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
        <meta content="utf-8" http-equiv="encoding">
        <title>Zip Get Test</title>
        <script  src="ZipTest.js" type='text/javascript'></script>
        <script  src="jszip.js" type='text/javascript'></script>

    </head>
<body>
    <input type="Button" id='btnBlob' value="Get image zip" onclick="GetZip2();">
    <a id="download_link" href="url">Download</a>
</body>

js code:

function GetZip(){
var filename = "BlueRefresh.png";

var xhr=new XMLHttpRequest();
xhr.open("GET", filename, false);
xhr.overrideMimeType('text/plain; charset=x-user-defined');   
xhr.send();

var data = xhr.responseText;

var zip = new JSZip();
zip.file(filename, data);

//make a blob out of the image string
var blob = zip.generate({type:"blob"});
var myLink = document.getElementById("download_link")
myLink.href = window.URL.createObjectURL(blob);
myLink.download = "Archive.zip";

}

function GetZip2(){
var filename = "BlueRefresh.png";

var xhr=new XMLHttpRequest();
xhr.open("GET", filename, false);
xhr.overrideMimeType('text/plain; charset=x-user-defined');   
xhr.send();

var data = xhr.responseText;

var s2 = "";
for (x = 0; x<data.length; ++x) {
  code = data.charCodeAt(x) & 0xff;
  s2 += String.fromCharCode(code);
}
data = s2;


var zip = new JSZip();
zip.file(filename, data);

//make a blob out of the image string
var blob = zip.generate({type:"blob"});
var myLink = document.getElementById("download_link")
myLink.href = window.URL.createObjectURL(blob);
myLink.download = "Archive.zip";

}

Upvotes: 2

Views: 4688

Answers (1)

oerl
oerl

Reputation: 1224

Had the same problem and I fixed it by adding the option binary : true to the zip.file function.

zip.file(filename, data, {binary : true});

Also by default jsZip uses STORE (no compression) so you may want to add compression : "DEFLATE" as well. Look here for description. http://stuk.github.io/jszip/documentation/api_jszip/file_data.html

zip.file(filename, data, {binary : true, compression : "DEFLATE"});

Upvotes: 2

Related Questions