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

React组件使用Knex获取数据库数据报错问题咨询

核心问题

你的实现思路从架构上就错了:React组件运行在终端用户的浏览器环境中,根本不能、也不允许直接连接数据库。
不管你把Knex相关的数据库操作文件移不移动到src目录,只要你试图在前端代码里直接import数据库操作逻辑,都不可能正常运行:浏览器没有Node.js运行环境,不支持net、fs等Node原生模块,Knex依赖的数据库驱动根本无法在浏览器里执行,你之前移动文件后触发的其他错误基本都是这个原因导致的。
你之前尝试用fetch调用http://localhost:3001接口的思路才是前后端分离场景下的正确方案,完全不需要在Express里写原生SQL——你之前写好的Knex操作逻辑完全可以直接在Express后端复用。


正确实现步骤

1. 拆分前后端代码职责

把项目代码按运行环境分成两个独立部分,不要混放:

  • 前端部分(React代码,存放在React项目的src/目录下):只负责页面渲染、交互逻辑,所有数据读写都通过HTTP请求调用后端接口获取
  • 后端部分(Express + Knex代码,存放在独立的后端服务目录,比如和React项目平级的server/文件夹):负责连接数据库、封装数据操作逻辑、对外提供HTTP接口

2. 调整后端Express代码

你之前写的db.js、library.js可以直接在后端复用,只需要新增对应接口路由即可,不需要写原生SQL:
后端服务入口文件(比如server/app.js)示例:

const express = require('express')
const cors = require('cors')
const library = require('./library') // 后端是Node环境,没有src目录导入限制,直接引用即可
const app = express()
const port = 3001

// 配置跨域,否则前端请求会被浏览器同源策略拦截
app.use(cors())

// 新增查询菜谱的接口
app.get('/api/recipes', async (req, res) => {
  try {
    const recipes = await library.getAllRecipes()
    res.json({
      code: 0,
      data: recipes
    })
  } catch (err) {
    res.status(500).json({
      code: 500,
      message: '查询菜谱失败'
    })
  }
})

app.listen(port, () => {
  console.log(`后端服务运行在 http://localhost:${port}`)
})

修正你之前library.js里的逻辑问题:

function getAllRecipes() {
  return db
    .readRecipes()
    .then((result) => {
      return result
    })
    .catch((err) => {
      logError(err)
      throw err // 把错误向上抛出,让上层路由能捕获到异常
    })
  // 删掉原代码finally块里的db.close(),不要每次操作完就关数据库连接
}

db.js的原有逻辑不需要改动,可以直接使用。

3. 调整前端React组件逻辑

删除组件里直接引用数据库文件的代码,改成通过HTTP请求调用后端接口:

const retrieveAllRecipes = async function () {
  try {
    const resp = await fetch('http://localhost:3001/api/recipes')
    const result = await resp.json()
    if (result.code === 0) {
      console.log(result.data)
      // 此处把返回的菜谱数据存入组件state,用于页面渲染即可
    }
  } catch (err) {
    console.error('请求失败', err)
  }
}

// 可以在组件挂载时(比如useEffect钩子、componentDidMount生命周期)调用上述方法即可

常见踩坑提醒
  • 不要在前端代码中引入任何仅能在Node.js环境运行的模块(包括数据库驱动、fs、path等系统模块),浏览器环境无法执行这类代码
  • Knex是服务端数据库操作工具,仅能在Node.js后端环境运行,不要把相关代码打包到前端产物中
  • 不要在单次数据库操作完成后调用db.close(),Knex默认使用连接池复用连接,每次操作后关闭连接会导致后续请求数据库连接异常,只需要在服务彻底关闭时再断开连接即可
  • 前后端分离联调时必须配置跨域,否则请求会被浏览器拦截

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 13:15:48