使用JavaScript生成可用EPUB遇阻:JSZip输出文件不可用求解决方案
问题:用JSZip生成的EPUB无法读取,求解决方案及Chrome扩展可用的库
我正尝试使用JSZip JavaScript库生成EPUB文件,但输出的epub.epub文件无法使用/读取。以下是我的无效代码:
// Create a new ZIP file var zip = new JSZip(); // Set the metadata for the book var metadata = '<?xml version="1.0"?>' + '<package xmlns="http://www.idpf.org/2007/opf">' + ' <metadata>' + ' <dc:title>My Book</dc:title>' + ' <dc:author>John Smith</dc:author>' + ' </metadata>' + ' <manifest>' + ' <item id="text" href="text.txt" media-type="application/xhtml+xml"/>' + ' <item id="toc" href="toc.ncx" media-type="application/x-dtbncx+xml"/>' + ' </manifest>' + ' <spine>' + ' <itemref idref="text"/>' + ' </spine>' + '</package>'; zip.file("content.opf", metadata); // Set the table of contents for the book var toc = '<?xml version="1.0"?>' + '<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">' + ' <head>' + ' <meta name="dtb:uid" content="book-id"/>' + ' <meta name="dtb:depth" content="1"/>' + ' <meta name="dtb:totalPageCount" content="0"/>' + ' <meta name="dtb:maxPageNumber" content="0"/>' + ' </head>' + ' <docTitle>' + ' <text>My Book</text>' + ' </docTitle>' + ' <navMap>' + ' <navPoint id="navpoint-1" playOrder="1">' + ' <navLabel>' + ' <text>Chapter 1</text>' + ' </navLabel>' + ' <content src="text.txt#xpointer(/html/body/p[1])"/>' + ' </navPoint>' + ' <navPoint id="navpoint-2" playOrder="2">' + ' <navLabel>' + ' <text>Chapter 2</text>' + ' </navLabel>' + ' <content src="text.txt#xpointer(/html/body/p[5])"/>' + ' </navPoint>' + ' </navMap>' + '</ncx>'; zip.file("toc.ncx", toc); // Add the text of the book to the ZIP file zip.file("text.txt", "Chapter 1 This is the text for chapter 1. Chapter 2 This is the text for chapter 2."); // Generate a downloadable EPUB file from the ZIP file zip.generateAsync({ type: "blob" }) .then(function (blob) { saveAs(blob, "epub.epub"); });
此前尝试过jEpub但被Chrome拦截,需要能在Chrome扩展中使用的库。
解决方案
代码中的关键错误及修正
你的代码不符合EPUB的核心规范,以下是必须修复的几点:
- 缺少强制的mimetype文件:EPUB要求根目录必须有
mimetype文件,内容为application/epub+zip,且不能被压缩。 - OPF文件不完整:缺少
dc:前缀的命名空间声明、package标签的版本与唯一标识属性。 - 媒体类型不匹配:
text.txt被标记为XHTML类型,实际是纯文本,需修正为text/plain。 - NCX锚点无效:用HTML结构的xpointer指向纯文本文件,阅读器无法识别,需简化路径。
修正后的完整代码
var zip = new JSZip(); // 添加强制的mimetype文件,必须放在最前面且不压缩 zip.file("mimetype", "application/epub+zip", { compression: "STORE" }); // 修正后的OPF文件 var metadata = '<?xml version="1.0" encoding="UTF-8"?>' + '<package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="book-id">' + ' <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">' + ' <dc:title>My Book</dc:title>' + ' <dc:author>John Smith</dc:author>' + ' <dc:identifier id="book-id">urn:uuid:your-unique-book-id-here</dc:identifier>' + ' </metadata>' + ' <manifest>' + ' <item id="text" href="text.txt" media-type="text/plain"/>' + ' <item id="toc" href="toc.ncx" media-type="application/x-dtbncx+xml"/>' + ' </manifest>' + ' <spine toc="toc">' + ' <itemref idref="text"/>' + ' </spine>' + '</package>'; zip.file("content.opf", metadata); // 修正后的NCX文件(移除无效xpointer) var toc = '<?xml version="1.0" encoding="UTF-8"?>' + '<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">' + ' <head>' + ' <meta name="dtb:uid" content="urn:uuid:your-unique-book-id-here"/>' + ' <meta name="dtb:depth" content="1"/>' + ' <meta name="dtb:totalPageCount" content="0"/>' + ' <meta name="dtb:maxPageNumber" content="0"/>' + ' </head>' + ' <docTitle>' + ' <text>My Book</text>' + ' </docTitle>' + ' <navMap>' + ' <navPoint id="navpoint-1" playOrder="1">' + ' <navLabel>' + ' <text>Chapter 1</text>' + ' </navLabel>' + ' <content src="text.txt"/>' + ' </navPoint>' + ' <navPoint id="navpoint-2" playOrder="2">' + ' <navLabel>' + ' <text>Chapter 2</text>' + ' </navLabel>' + ' <content src="text.txt"/>' + ' </navPoint>' + ' </navMap>' + '</ncx>'; zip.file("toc.ncx", toc); // 添加纯文本内容 zip.file("text.txt", "Chapter 1\n\nThis is the text for chapter 1.\n\nChapter 2\n\nThis is the text for chapter 2."); // 生成EPUB文件 zip.generateAsync({ type: "blob" }) .then(function (blob) { saveAs(blob, "epub.epub"); });
适合Chrome扩展的EPUB生成库
如果不想手动处理EPUB规范细节,推荐以下库:
- epub-gen:轻量纯前端库,直接传入JSON格式的书籍数据即可生成EPUB,无需手动拼接XML,兼容性好,符合Chrome扩展环境要求。
- EpubJS:兼具EPUB生成与阅读器功能,代码模块化,可按需引入,适配Chrome扩展的内容安全政策。
使用第三方库时,优先选择纯ES模块或UMD格式版本,避免使用含eval或内联脚本的代码,确保符合Chrome扩展的CSP规则。
内容的提问来源于stack exchange,提问作者Naoufal EL JAOUHARI
相关产品推荐
相关产品推荐

