futurepress / epub.js

Enhanced eBooks in the browser.
http://futurepress.org
Other
6.42k stars 1.1k forks source link

Error while trying to open epub from blob #873

Open AndreevskiAleksandar opened 5 years ago

AndreevskiAleksandar commented 5 years ago

Hello, I am trying to download epubs from a server and then open them with the epub.js library. I dont supply the url directly to the ePub library like in the examples (ePub('url')), since the books can get up to 100mb, so I cache them, and then try to open them with epub.js. The problem is when I try to supply the binary file or as a blob right after downloading it with XHR, the library does not throw any kind of error, but also does not show anything. It works fine when I supply the url directly and the epub.js loads the file itself.

The code that I try to execute is the following.

` var oReq = new XMLHttpRequest();

    oReq.onload = function (e) {
        var arraybuffer = oReq.response;
        var reader = new FileReader();
        reader.addEventListener("load", function () {
            var book = ePub(reader.result, { openAs: 'binary' });
            var rendition = book.renderTo('area', {
                width: 300,
                height: 500
            });
            var displayed = rendition.display();
        }, false);
        if (oReq.response) {
            var blob = new Blob([oReq.response], { type: "application/epub+zip" });
            reader.readAsArrayBuffer(blob);
        }
    }
    oReq.open("GET", 'http://localhost:4000/books/download.epub');
    oReq.send();

`

Also after some tinkering with the code and debugging the epub.js library, I found the problematic code. In the openEpub function there is this code

 function openEpub(data, encoding) {
            var _this2 = this;
            console.log(data);
            return this.unarchive(data, encoding || this.settings.encoding).then(function () {
                return _this2.openContainer(CONTAINER_PATH)
            }).then(function (packagePath) {
                return _this2.openPackaging(packagePath);
            });
        }

I added a catch at the end to log an error .catch(err => console.error(err)); and I got this error that points to the jszip library. epub.js:11669 Error: End of data reached (data length = 447427, asked index = 508794). Corrupted zip ?

The file is not corrupted, its length is 447427 bytes. I dont know why the decompression tries to find index that is 6000 bytes away...

On another book the error is Corrupted zip: missing 860709509 bytes. Again the size is around 300000 bytes.

The books I am using are: https://www.gutenberg.org/ebooks/1661 and the second one is Moby Dick from the example http://s3.amazonaws.com/moby-dick/moby-dick.epub

tuphan-dn commented 5 months ago

Hopefully it's helpful to you

import { Book } from 'epubjs'

const blob: Blob = ... // Blob from HTTP request or file uploading

const buf = await blob.arrayBuffer()
const book = new Book(buf as any, { openAs: 'binary' })

The line buf as any is because of the incorrect type definition in epubjs, however, it's ok to use.