You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 19:45:30