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

Web Worker调用Sqlite3报错:require函数未定义问题求助

问题:浏览器Web Worker中无法使用Node.js的sqlite3模块

在BeagleBone Black上托管的网页中,我尝试通过JavaScript Web Worker从Sqlite3数据库读取数据并展示。基于数字计数的Web Worker示例运行正常,但修改后的Worker代码在终端运行时可以正常访问数据库,作为Web Worker运行时,两款浏览器均提示“require(Sqlite3)函数未定义”。我已经重装了Node.js和sqlite3扩展,但问题依然存在。

相关代码

HTML代码(wkr_tst.html)

<!DOCTYPE html>
<html>
<body>

<p>Count numbers: <output id="result"></output></p>
<p>Count numbers: <output id="result2"></output></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button>

<script>
var w;

function startWorker() {
  if (typeof(Worker) !== "undefined") {
    if (typeof(w) == "undefined") {
      w = new Worker("dbase1.js");
    }
    w.onmessage = function(event) {
      document.getElementById("result").innerHTML = event.data;
      document.getElementById("result2").innerHTML = event.data;
    };
  } else {
    document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
  }
}

function stopWorker() {
  w.terminate();
  w = undefined;
}
</script>

</body>
</html>

JavaScript Worker代码(dbase1.js)

const sqlite3 = require("sqlite3")
var i = 0;
const db = new sqlite3.Database("/home/debian/examples/C_BMS/test2.db",sqlite3.OPEN_READONLY );

function timedCount() {
    i=i+1;
   db.all("SELECT * FROM EpiData", [], (err, rows) => {
        console.log(rows);
    })
postMessage(rows);
//postMessage(i);
//postMessage(i+2);
//setTimeout("timedCount()",500);
}
timedCount(); 
db.close();

问题原因及解决方案

核心原因

浏览器环境(包括Web Worker)不支持Node.js的require()函数,也无法直接运行Node.js专用的sqlite3模块。终端能运行是因为处于Node.js环境,而浏览器是独立的前端运行环境,两者的API和模块机制完全不同。

可行解决方案

方案1:通过后端接口中转数据(推荐)

这是最稳妥的生产级方案:

  • 在BeagleBone Black上搭建一个简单的Node.js后端服务(比如用Express),编写接口来查询Sqlite3数据库并返回数据。
  • 前端(包括Web Worker)通过fetch()调用这个后端接口获取数据,再进行展示。

示例后端代码(Express):

const express = require('express');
const sqlite3 = require('sqlite3').verbose();
const app = express();
const port = 3000;

// 连接数据库
const db = new sqlite3.Database('/home/debian/examples/C_BMS/test2.db', sqlite3.OPEN_READONLY);

// 定义查询接口
app.get('/api/epidata', (req, res) => {
  db.all('SELECT * FROM EpiData', [], (err, rows) => {
    if (err) {
      res.status(500).json({ error: err.message });
      return;
    }
    res.json(rows);
  });
});

// 允许跨域(如果前端和后端端口/域名不同)
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET');
  next();
});

app.listen(port, () => {
  console.log(`Server running on http://你的BeagleBoneIP:${port}`);
});

修改后的Web Worker代码(dbase1.js):

function fetchData() {
  fetch('http://你的BeagleBoneIP:3000/api/epidata')
    .then(response => response.json())
    .then(rows => {
      postMessage(rows);
    })
    .catch(err => {
      console.error('获取数据失败:', err);
    });
}

fetchData();

方案2:使用前端兼容的SQLite库

如果不想搭建后端,可以使用前端能直接运行的SQLite实现(如sql.js):

  • 下载sql.js的预编译文件并引入到项目中。
  • 在Web Worker中加载数据库文件(需确保文件可被前端访问,或转成Base64嵌入),再执行查询。

注意:这种方式适合小型数据库场景,性能和资源占用不如后端中转,且数据库文件会暴露给前端。

额外问题修复

原Worker代码中,postMessage(rows)写在db.all()的回调函数外面,此时rows还未被异步赋值,会传递undefined。需将postMessage移到回调内部:

db.all("SELECT * FROM EpiData", [], (err, rows) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(rows);
  postMessage(rows); // 移到这里
})

内容的提问来源于stack exchange,提问作者MikeD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:25:10