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

如何从JavaScript文件获取变量值上传MongoDB而非HTML表单

问题背景

目前已实现HTML表单提交数据到后端、存入MongoDB的基础功能,相关代码如下:

  • 前端表单代码:
<form class="container" method="post">
    <div class="form-group">
        <input class="form-control" name="title">
    </div>
    <textarea class="form-control" name="content"></textarea>
    <button>add to mongodb</button>
</form>
  • 后端接收存储代码:
app.post("/", function(req, res) {
    let newGameData = new gameData ({
        score: req.body.title,
        jumps: req.body.content,
    });
    newGameData.save();
    res.redirect('/')
})
待实现需求

当前不需要从HTML表单取值,需要获取嵌入页面的独立游戏JS文件里的运行时变量。该JS中定义了两个随游戏进程持续追加数据的全局数组:

var score = [];
var jumps = [];

两个数组会随着游戏分数提升、角色触发跳跃操作持续追加数据,需要实现三个核心目标:

  • 玩家每次游戏生命结束时,追加对应分数记录
  • 定期将游戏运行产生的这部分数据上传至MongoDB存储
  • 支持从MongoDB拉取最高分数据,在前端页面展示

之前考虑过先把数据写入JSON文件再上传MongoDB,但不确定方案是否合理、也不清楚具体实现流程,需要可落地的实现思路。

实现方案

不需要先写本地JSON文件再上传,前端运行时产生的JS变量可以直接通过接口提交到后端,流程和你之前写的表单提交逻辑本质一致,只是提交触发时机、提交的数据来源从表单输入框改成了JS运行时变量。浏览器端JS运行在用户本地环境,没有直接写入本地文件的权限,写JSON再上传的方案本身不具备可行性。

1. 后端接口调整

你现有的POST接口可以直接复用,只需要调整参数匹配逻辑,新增JSON请求体解析中间件,再加一个获取最高分的GET接口即可:

// 先加这行中间件,否则后端无法解析前端传的JSON格式请求体,放在路由定义前面
app.use(express.json())

// 调整原有提交数据接口
app.post("/api/gamedata", function(req, res) {
    let newGameData = new gameData ({
        score: req.body.score, // 直接接收前端传过来的score数组/单次分数
        jumps: req.body.jumps, // 直接接收前端传过来的jumps数组
        recordTime: Date.now() // 可选,加记录时间方便后续做数据统计
    });
    newGameData.save().then(()=>{
        res.send({code:200, msg:"保存成功"})
    }).catch(err=>{
        res.send({code:500, msg:"保存失败"})
    })
})

// 新增获取最高分接口
app.get("/api/highestscore", async function(req, res) {
    // 按score字段倒序取第一条记录,即为历史最高分
    const highestRecord = await gameData.findOne().sort({score: -1})
    res.send({
        code:200,
        data: highestRecord?.score || 0
    })
})

2. 前端游戏JS逻辑修改

(1)游戏结束时触发数据提交

找到游戏逻辑里判定玩家生命结束的代码位置,在游戏结束的回调函数里直接读取全局的score和jumps变量,通过fetch提交到后端接口即可:

// 在你已有的游戏结束处理函数里加入以下逻辑
function gameOver() {
    // 保留你原本的游戏结束逻辑,比如弹出结算面板、停止帧动画、重置游戏状态等
    // ...
    
    // 提交当前局数据到后端
    fetch("/api/gamedata", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            score: score, // 直接传入当前全局作用域下的score数组
            jumps: jumps  // 直接传入当前全局作用域下的jumps数组
        })
    }).then(res=>res.json()).then(res=>{
        if(res.code === 200) {
            // 提交成功后清空当前局的数组,为下一局游戏做准备
            score = []
            jumps = []
        }
    })

    // 拉取历史最高分渲染到页面
    fetch("/api/highestscore").then(res=>res.json()).then(res=>{
        if(res.code ===200) {
            // 将返回的最高分写入页面对应的DOM节点即可
            document.querySelector("#highest-score").textContent = res.data
        }
    })
}

(2)定期上传备份实现

如果需要在游戏过程中定期上传备份数据、不用等游戏结束再传,直接加个定时任务即可:

// 页面加载完成后启动定时器,每30秒上传一次当前数据,间隔可自行调整
setInterval(()=>{
    // 只有当前数组存在数据时才发起请求,避免无意义的空请求
    if(score.length >0 || jumps.length>0) {
        fetch("/api/gamedata", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({
                score: [...score], // 拷贝一份当前数据传递,避免上传过程中数组变化导致数据异常
                jumps: [...jumps]
            })
        })
    }
}, 30000) // 单位为毫秒

3. 注意事项

  • 如果游戏单局时长较短,可以不做定期上传逻辑,仅在游戏结束时传一次数据即可,减少不必要的接口请求。
  • 如果需要区分不同玩家的数据,可以在提交数据时额外加上用户标识字段,后端存储时同步记录即可。
  • 前端提交前可以对数据做简单校验,避免异常数据写入数据库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 07:45:30