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

Node.js项目集成MySQL写入游戏得分数据不生效问题

问题根因
  • 核心错误是运行环境混淆:你把只能在Node.js服务端运行的数据库操作代码,直接写到了前端页面的<script>标签中。浏览器环境既不支持CommonJS规范的require()语法,也无法直接加载mysql这个Node.js专属npm包,这段代码在浏览器加载时就会直接抛出语法/运行时错误,根本不会执行到数据库写入逻辑。
  • 你单独跑通的测试代码是直接在Node.js运行时执行的,和用户浏览器里运行的前端代码属于完全隔离的两个运行环境,环境差异是数据写不进去的核心原因。
  • 附带逻辑缺陷:就算忽略环境问题,你原有写法在调用connection.query()发起异步查询后,立刻执行connection.end()关闭连接,查询请求还没来得及发送到MySQL就被断开,同样会导致写入失败;另外直接拼接SQL字符串存在SQL注入风险,页面里的表格闭合标签误写为</tabl>也会造成DOM渲染异常。
修复方案

整体遵循「前端只做交互和请求、服务端处理数据库操作」的前后端分层逻辑,不要在前端写任何数据库相关代码:

  • 第一步:在Node.js服务端新增得分上报接口
    找到你启动本地Web服务的Node.js入口文件,新增HTTP接口处理得分写入、榜单查询逻辑,推荐使用MySQL连接池复用连接,避免频繁建连销毁的性能损耗,参考代码:
// 以下代码写在Node.js服务端文件中,不要写入前端HTML
const express = require('express') // 若使用其他Web框架,逻辑保持一致即可
const mysql = require('mysql')
const app = express()
// 解析POST请求的JSON格式参数
app.use(express.json())

// 初始化MySQL连接池
const dbPool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: '441441',
  database: 'app',
  connectionLimit: 10 // 保留10个连接复用
})

// 得分上报接口
app.post('/api/report-score', (req, res) => {
  const { userName, score } = req.body
  // 基础参数校验
  if (!userName || typeof score !== 'number') {
    return res.status(400).json({ code: 1, msg: '参数非法' })
  }
  // 用参数化查询执行写入,避免SQL注入
  const insertSql = 'INSERT INTO top5(Name, Score) VALUES (?, ?)'
  dbPool.query(insertSql, [userName, score], (insertErr) => {
    if (insertErr) {
      console.error('得分写入失败:', insertErr)
      return res.status(500).json({ code: 1, msg: '写入失败' })
    }
    // 写入成功后查询Top5榜单返回给前端
    const rankSql = 'SELECT Name AS userName, Score AS score FROM top5 ORDER BY Score DESC LIMIT 5'
    dbPool.query(rankSql, (rankErr, rankList) => {
      if (rankErr) {
        console.error('榜单查询失败:', rankErr)
        return res.status(500).json({ code: 1, msg: '榜单查询失败' })
      }
      res.json({ code: 0, data: rankList })
    })
  })
})

// 保留你原有的静态页面托管逻辑,比如托管HTML、JS、CSS静态资源
// app.use(express.static('./public'))

// 启动服务,端口和你原有配置保持一致即可
app.listen(3000, () => {
  console.log('服务已启动')
})
  • 第二步:修改前端弹球命中逻辑
    把前端<script>里所有require('mysql')、创建数据库连接、执行SQL的代码全部删除,命中槽位计算出对应分值后,通过HTTP请求调用刚才写的服务端接口即可,参考修改:
// 以下代码运行在浏览器端,不要出现任何数据库账号、连接相关逻辑
function getBucket(chip) {
  let total = 0
  $.each(chip.path, function(i, e) {
    total += e
  })

  let score = 0
  switch(total) {
    case -4:
    case 4:
      score = 50
      break
    case -2:
    case 2:
      score = 1
      break
    case 0:
      score = 10
      break
    default:
      $(chip.el).remove()
      return
  }

  // 上报得分到服务端
  fetch('/api/report-score', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      userName: data.describe, // 对应当前得分的用户名称
      score: score
    })
  })
  .then(res => res.json())
  .then(res => {
    if (res.code === 0) {
      // 写入成功,用返回的Top5数据更新页面榜单
      renderRankBoard(res.data) // 自行实现榜单渲染逻辑,把数据插入到页面对应位置
    }
  })
  .catch(err => console.error('得分上报失败:', err))

  $(chip.el).remove()
}
  • 额外修复点:把你页面里写错的表格闭合标签</tabl>改成</table>,避免DOM渲染异常。

安全提示:绝对不要在前端代码里写数据库连接地址、账号、密码,所有数据库操作必须收口到服务端,否则任何人打开浏览器控制台就能拿到你的数据库权限,随意删改数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:09:58