如何实现刷新后状态保留的复选框?PATCH请求未写入db.json排查
问题分析与解决方案
核心问题点
- 同步文件写入的回调无效:
fs.writeFileSync是同步API,不支持回调函数,你写的错误处理回调根本不会触发,写入出错也无法捕获。 - PATCH请求错误替换整个对象:直接用仅含
completed字段的newTodo替换原Todo对象,会丢失id、title等原有字段,导致写入的数据缺少id,后续查找匹配失败。 - ID类型不匹配:路由参数的
id是字符串,而db.json中的id大概率是数字,用===严格相等比较会找不到对应项,实际未修改数据。 - 状态码使用错误:202表示请求已接受但未处理完成,此处应使用200(成功返回数据)或204(成功无返回内容)。
修正后的后端代码
app.patch("/todo/:id", (req, res) => { const { id } = req.params; // 统一ID类型:将字符串id转为数字(若db中id是字符串则去掉此步) const targetId = Number(id); try { let rawdata = fs.readFileSync("db.json", "utf8"); let content = JSON.parse(rawdata); const todoIndex = content.findIndex((i) => i.id === targetId); if (todoIndex === -1) { return res.status(404).json({ message: "Todo with that id not found" }); } // 仅更新completed字段,保留原有所有其他字段 content[todoIndex].completed = req.body.completed; // 同步写入文件,用try/catch捕获错误 fs.writeFileSync("db.json", JSON.stringify(content, null, 2)); // 返回修改后的完整Todo对象 res.status(200).json(content[todoIndex]); } catch (err) { console.error(err); res.status(500).json({ message: "Failed to update todo" }); } });
前端代码优化(可选)
async function editCheckbox(id) { try { // 用const声明变量,避免全局污染 const checkbox = { completed: document.querySelector(`[data-id="${id}"] input[type="checkbox"]`).checked }; const response = await fetch(`http://localhost:8080/todo/${id}`, { method: 'PATCH', body: JSON.stringify(checkbox), headers: { 'Content-Type': 'application/json; charset=utf-8', }, }); // 增加响应状态判断,处理请求失败场景 if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const updatedTodo = await response.json(); console.log("Todo updated:", updatedTodo); } catch (err) { console.error("Update failed:", err); } }
额外检查项
- 确认
db.json中的id类型(数字/字符串),保证与后端转换后的类型一致。 - 检查服务器对
db.json文件有写入权限(避免文件只读)。 - 确保前端调用
editCheckbox时传入的id与数据库中的id完全匹配。
内容的提问来源于stack exchange,提问作者Volodymyr Khabarov
相关产品推荐
相关产品推荐

