jszip icon indicating copy to clipboard operation
jszip copied to clipboard

Problem: Error: Can't find end of central directory

Open reselbob opened this issue 2 years ago • 3 comments

Hi:

I am trying to get JSZip to uncompress data coming out of the Stack Exchange API.

I keep getting this error

jszip.js:13 Uncaught (in promise) Error: Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html  jszip,js:13

According to Stack Exchange:

Additionally, all API responses are compressed. The Content-Encoding header is always set, but some proxies will strip this out. The proper way to decode API responses can be found here.

Here is the code I am trying to execute:

    var url = 'https://api.stackexchange.com/2.3/questions?order=desc&sort=activity&tagged=edgeEngine&site=stackoverflow'

    // Attach click handler to login button
    $('#login-button').click(async function () {
        //alert('hi')
        const options = {
            headers: new Headers({ 'Access-Control-Allow-Origin': '*' }, {'Accept-Encoding': 'gzip'}),

        };
        const response = await fetch(url, options);
        const reader = response.body.getReader();
        let blob = null;
        while (true) {
            const { value, done } = await reader.read();
            if (done) break;
            console.log({received: value});
            blob = value
        }
        JSZip.loadAsync(blob).then(function (zip) {
            console.log(zip);
        });
    })

It seems to be blowing up on : JSZip.loadAsync(blob)

Here is a screenshot of the debug verifying that I am getting data from the Stack Exchange API.

stackapi-dump-09-04-2021

Any help you can provide will be very helpful.

Thanks in advance.

Bob

reselbob avatar Sep 04 '21 20:09 reselbob

Hi: Turns out my issue really had nothing to do with JSZIP. Here is the solution I came up with the get a result from the Stack Exchange API. Just did some stitching from a lot of sources. Hope this help someone:

<!DOCTYPE html>
<html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>
    <h1>Stack Exchange</h1>
    <p>API Query</p>
    <p>https://api.stackexchange.com/2.3/questions?order=desc&sort=activity&tagged=jszip&site=stackoverflow'</p>
    <button id="login-button">Get API Data</button>
    <pre></pre>
</body>

<script type='text/javascript'>
    var url = 'https://api.stackexchange.com/2.3/questions?order=desc&sort=activity&tagged=jszip&site=stackoverflow'

    // Attach click handler to login button
    $('#login-button').click(async function () {
        //alert('hi')
        const options = {
            headers: new Headers({ 'Access-Control-Allow-Origin': '*' }, { 'Accept-Encoding': 'gzip' }),

        };
        fetch(url, options)
            .then(response => response.body)
            .then(rb => {
                const reader = rb.getReader();
                return new ReadableStream({
                    start(controller) {
                        // The following function handles each data chunk
                        function push() {
                            // "done" is a Boolean and value a "Uint8Array"
                            reader.read().then(({ done, value }) => {
                                // If there is no more data to read
                                if (done) {
                                    controller.close();
                                    return;
                                }
                                // Get the data and send it to the browser via the controller
                                controller.enqueue(value);
                                // Check chunks by logging to the console
                                push();
                            })
                        }

                        push();
                    }
                });
            })
            .then(stream => {
                // Respond with our stream
                return new Response(stream, { headers: { "Content-Type": "text/html" } }).text();
            })
            .then(result => {
                // Show the result in the browser
                $('pre').html(JSON.stringify(JSON.parse(result), null, 4));
            });
    })

</script>
</html>

reselbob avatar Sep 05 '21 05:09 reselbob

I had the same issue, but in the backend (node), I swapped compressing for adm-zip, and then it didn't appear

liangchaoshun avatar Jan 16 '23 12:01 liangchaoshun

JSZip cannot be used in browser ?!

brady-man-847 avatar Dec 20 '23 06:12 brady-man-847