如何在Chrome扩展(Manifest V3)中打开EPUB文件?
解决Chrome扩展Manifest V3下EPUB自动下载问题(无需额外页面)
问题根源
Chrome内置PDF阅读器,但原生不支持EPUB文件,所以遇到EPUB链接时会直接触发下载流程。你现有的tabs.onUpdated监听逻辑是在页面更新后跳转,此时浏览器已经启动下载,无法阻止,因此无效。
解决方案:拦截请求+页面内渲染
通过拦截EPUB请求阻止默认下载行为,然后在当前页面注入EPUB阅读器脚本,直接在原标签页内渲染EPUB内容,无需额外的viewer页面。
1. 配置Manifest V3权限
在manifest.json中添加必要权限和资源配置:
{ "manifest_version": 3, "name": "Inline EPUB Viewer", "version": "1.0", "permissions": ["declarativeNetRequest", "activeTab", "scripting"], "host_permissions": ["<all_urls>"], "declarative_net_request": { "rule_resources": [ { "id": "epub_intercept", "enabled": true, "path": "rules.json" } ] }, "web_accessible_resources": [ { "resources": ["lib/epub.min.js"], "matches": ["<all_urls>"] } ] }
2. 编写请求拦截规则
创建rules.json文件,拦截主框架的EPUB请求并添加标识参数,以便后续处理:
[ { "id": 1, "priority": 1, "action": { "type": "redirect", "redirect": { "transform": { "queryTransform": { "addOrReplace": [{"key": "inline_epub", "value": "1"}] } } } }, "condition": { "urlFilter": "*.epub", "resourceTypes": ["main_frame"] } } ]
3. 后台服务工作者脚本(service-worker.js)
监听标签更新,识别带标识的EPUB请求,注入阅读器资源:
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => { if (changeInfo.url && changeInfo.url.includes('.epub') && changeInfo.url.includes('inline_epub=1')) { // 注入EPUB阅读器库和渲染脚本 await chrome.scripting.executeScript({ target: { tabId }, files: ['lib/epub.min.js', 'render-epub.js'] }); // 注入阅读器样式 await chrome.scripting.insertCSS({ target: { tabId }, files: ['viewer-styles.css'] }); } });
4. 页面内渲染脚本(render-epub.js)
清空当前页面内容,初始化EPUB阅读器:
// 清空原页面内容 document.body.innerHTML = ''; document.body.style.margin = '0'; document.body.style.padding = '20px'; // 创建阅读器容器 const readerContainer = document.createElement('div'); readerContainer.id = 'epub-reader'; readerContainer.style.width = '100%'; readerContainer.style.height = 'calc(100vh - 40px)'; document.body.appendChild(readerContainer); // 获取EPUB文件URL const currentUrl = new URL(window.location.href); const epubUrl = currentUrl.searchParams.get('file') || currentUrl.href.split('?')[0]; // 初始化epub.js阅读器 const book = ePub(epubUrl); const rendition = book.renderTo('epub-reader', { width: '100%', height: '100%' }); rendition.display();
5. 阅读器样式(viewer-styles.css)
添加基础样式优化显示:
#epub-reader { border: 1px solid #eee; border-radius: 4px; overflow: hidden; }
注意事项
- 需下载
epub.js库的压缩版,放到扩展目录的lib文件夹下。 - 如果仅需处理特定域名的EPUB文件,可将
host_permissions中的<all_urls>替换为对应域名,提升安全性。
内容的提问来源于stack exchange,提问作者Dianne
相关产品推荐
相关产品推荐

