如何在Chrome扩展中内置预构建SQLite数据库并实现单词查询?
解决方案:在Chrome扩展中使用预构建SQLite词典数据库
一、可行性说明
当然可以将预构建的SQLite数据库集成到Chrome扩展中。Chrome扩展支持加载本地资源,结合SQLite的WASM版本,就能实现离线查询词典的功能。
二、具体实现步骤
1. 准备资源
- 将
dictionarydb.sqlite放到扩展根目录 - 获取SQLite WASM预编译包:下载
sqlite3.js和sqlite3.wasm(从SQLite官方预编译资源提取即可),同样放到扩展根目录 - 更新
manifest.json,确保背景页能访问这些资源,示例配置:
{ "manifest_version": 3, "name": "离线词典扩展", "version": "1.0", "background": { "service_worker": "background.js" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ], "web_accessible_resources": [ { "resources": ["dictionarydb.sqlite", "sqlite3.js", "sqlite3.wasm"], "matches": ["<all_urls>"] } ] }
2. 初始化SQLite并加载数据库(修改background.js)
在background.js中完成数据库初始化和查询逻辑:
// 全局变量保存数据库实例 let dbInstance = null; // 初始化SQLite和数据库 async function initDictionaryDB() { // 加载SQLite WASM模块 const sqliteModule = await import('./sqlite3.js'); await sqliteModule.default(); // 读取预构建的数据库文件 const dbResponse = await fetch(chrome.runtime.getURL('dictionarydb.sqlite')); const dbBuffer = await dbResponse.arrayBuffer(); // 以只读模式打开数据库 dbInstance = new sqliteModule.SQLite3.DB(new Uint8Array(dbBuffer), 'r'); } // 启动时初始化数据库 initDictionaryDB(); // 查询单词释义的函数(需根据你的数据库表结构调整SQL) function getWordMeaning(word) { if (!dbInstance) return null; try { // 假设表名为words,字段为word和meaning,按需修改 const stmt = dbInstance.prepare(`SELECT meaning FROM words WHERE word = ?`); stmt.bind([word]); const result = stmt.get(); stmt.finalize(); return result ? result.meaning : "未找到该单词的释义"; } catch (error) { console.error("查询出错:", error); return "查询失败"; } } // 处理content.js的消息请求 chrome.runtime.onMessage.addListener(async (request, sender) => { if (request.selectedText) { // 确保数据库初始化完成 if (!dbInstance) await initDictionaryDB(); const textMeaning = getWordMeaning(request.selectedText.trim()); chrome.tabs.sendMessage(sender.tab.id, { from: "background", meaning: textMeaning }); } });
3. 优化内容脚本的展示逻辑(可选)
原代码用alert展示释义,可改成浮动面板更贴近谷歌词典体验,修改content.js:
// 创建浮动释义面板 function createPopupPanel() { const panel = document.createElement('div'); panel.style.cssText = ` position: fixed; background: #fff; border: 1px solid #e0e0e0; border-radius: 6px; padding: 12px; box-shadow: 0 2px 12px rgba(0,0,0,0.15); z-index: 999999; display: none; max-width: 320px; font-size: 14px; `; document.body.appendChild(panel); return panel; } const popupPanel = createPopupPanel(); // 监听文本选中事件 document.addEventListener("mouseup", (event) => { const selectedText = window.getSelection().toString().trim(); if (selectedText.length) { chrome.runtime.sendMessage({ selectedText }); // 定位面板到选中区域右侧 const selectionRect = window.getSelection().getRangeAt(0).getBoundingClientRect(); popupPanel.style.left = `${selectionRect.right + 12}px`; popupPanel.style.top = `${selectionRect.top}px`; } else { popupPanel.style.display = 'none'; } }); // 接收并展示释义 chrome.runtime.onMessage.addListener((msg) => { if (msg.from === "background") { popupPanel.textContent = `释义:${msg.meaning}`; popupPanel.style.display = 'block'; } }); // 点击页面其他区域关闭面板 document.addEventListener('mousedown', (e) => { if (!popupPanel.contains(e.target)) { popupPanel.style.display = 'none'; } });
三、注意事项
- 务必根据你的SQLite数据库实际表结构调整查询语句中的表名、字段名
- Manifest V3的service worker是无DOM环境,需注意异步初始化的时机,避免未完成初始化就执行查询
- 测试时加载已解压的扩展包,确保所有资源路径正确
提前感谢您的帮助
内容的提问来源于stack exchange,提问作者KonTash
相关产品推荐
相关产品推荐

