Express与Vue搭配更新后端JSON文件无需重启服务器问题咨询
问题原因
- 首先是后端接口重复返回响应,触发
ERR_HTTP_HEADERS_SENT报错:一个HTTP请求只能返回一次响应,你在/addwords接口中连续调用res.send(words)、res.status(201).send()、res.end(),相当于尝试多次返回响应,直接触发报错。 - 其次是数据不更新的核心原因有两个:
editJSON是异步操作,你调用该方法后立刻返回数据,此时文件读写还没完成,返回的是修改前的旧数据- 你服务端返回的
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
相关产品推荐
相关产品推荐

