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

Express与Vue搭配更新后端JSON文件无需重启服务器问题咨询

问题原因

  • 首先是后端接口重复返回响应,触发ERR_HTTP_HEADERS_SENT报错:一个HTTP请求只能返回一次响应,你在/addwords接口中连续调用res.send(words)、res.status(201).send()、res.end(),相当于尝试多次返回响应,直接触发报错。
  • 其次是数据不更新的核心原因有两个:
    1. editJSON是异步操作,你调用该方法后立刻返回数据,此时文件读写还没完成,返回的是修改前的旧数据
    2. 你服务端返回的words变量是服务启动时加载到内存的,修改磁盘上的JSON文件不会自动更新内存中的变量,所以哪怕文件改完了,接口返回的还是启动时的旧数据,只有重启服务才会重新读取文件更新内存变量

修正方案

第一步:改造服务端代码

首先将editJSON改为异步Promise版本,确保文件写入完成后再返回最新数据,同时接口统一单次返回响应:

const fs = require('fs').promises
const path = require('path')
// 用绝对路径避免相对路径出错
const wordsFilePath = path.join(__dirname, './assets/words.json')

// 改造后的编辑方法,返回Promise,写入完成后返回最新数据
async function editJSON(fr, en, es) {
  // 每次都读取磁盘上的最新文件,不用内存缓存的变量
  const jsonContent = await fs.readFile(wordsFilePath, 'utf-8')
  const wordData = JSON.parse(jsonContent)
  wordData.list_words.push({ fr, en, es })
  const newJsonContent = JSON.stringify(wordData, null, 2)
  await fs.writeFile(wordsFilePath, newJsonContent, 'utf-8')
  return wordData
}

// 改造/addwords接口
app.post('/addwords', async (req, res) => {
  try {
    const { fr, en, es } = req.body
    // 等待文件写入完成,拿到最新的全量数据
    const updatedData = await editJSON(fr, en, es)
    // 单次返回响应即可
    res.status(201).send(updatedData)
  } catch (err) {
    console.error('操作失败', err)
    res.status(500).send({ error: '数据更新失败' })
  }
})

// 如果你之前是用express.static托管words.json,替换成主动读文件的接口,避免静态资源缓存
app.get('/words.json', async (req, res) => {
  try {
    const jsonContent = await fs.readFile(wordsFilePath, 'utf-8')
    // 禁用缓存,避免浏览器读旧数据
    res.setHeader('Cache-Control', 'no-store')
    res.send(JSON.parse(jsonContent))
  } catch (err) {
    console.error('读取失败', err)
    res.status(500).send({ error: '数据读取失败' })
  }
})

第二步:前端代码调整

无需额外修改,保持你之前的逻辑即可,接口返回的已经是最新数据,赋值后Vue会自动刷新视图:

async addWord () {
  const obj = {
    fr: this.words_input.fr,
    en: this.words_input.en,
    es: this.words_input.es
  }
  const res = await axios.post('http://localhost:3000/addwords', obj)
  this.words_init = res.data.list_words
  // 可选:提交后清空输入框
  this.words_input = { fr: '', en: '', es: '' }
}

如果仍然存在缓存问题,可以在GET请求words.json时加时间戳参数,强制跳过浏览器缓存:

await axios.get(`http://localhost:3000/words.json?t=${Date.now()}`)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 01:45:02