MVC全栈项目报错:Get请求JSON输入意外结束求助
问题分析与解决方案
错误原因
后端响应格式不一致
当查询不到支出数据时,后端将req.expense赋值为纯字符串No expenses were found on this date.,虽然res.json()会将其转为JSON字符串,但如果后端返回错误状态码(如400)时响应体格式不符合JSON规范,前端解析就会失败。此外,create接口成功时返回纯文本而非JSON,虽不影响当前GET请求,但属于接口格式不统一的问题。前端未处理响应异常与Promise拒绝
fetchExpenses函数未判断响应状态(res.ok),无论后端返回成功还是错误状态,都直接调用res.json()。如果后端返回错误时响应体为空或非有效JSON,就会触发Unexpected end of JSON input语法错误。- 视图层调用
fetchExpenses时未添加catch捕获异常,导致未处理的Promise拒绝,触发Unhandled Rejection错误。
修复方案
后端调整
- 统一返回JSON格式
修改expenseByDate中无数据的处理逻辑,返回结构化JSON而非纯字符串:exports.expenseByDate = async (req, res, next, date) => { try { const expenseQuery = await pool.query( 'SELECT * FROM expenses WHERE created_at BETWEEN $1 AND $2', [ startOfDay(new Date(Number(date))).toISOString(), endOfDay(new Date(Number(date))).toISOString(), ] ); const expenseList = expenseQuery.rows; req.expense = expenseList.length > 0 ? expenseList : { message: "No expenses were found on this date." }; // 改为JSON对象 return next(); } catch (error) { return res.status(400).json({ error: error.message }); // 确保错误信息结构化 } }; - 修复create接口的响应格式
将create接口的成功响应改为JSON格式:// 替换原send语句 return res.status(201).json({ message: `Expense added: ${newExpense.rows[0].title}` });
前端调整
- 在fetch函数中处理响应状态
修改fetchExpenses,先检查响应是否正常,再解析JSON,异常时抛出错误:export const fetchExpenses = async (date) => { const selectDate = new Date(date).getTime() || new Date().getTime(); const res = await fetch(`/api/expense/list/${selectDate}`); console.log('result', res); if (!res.ok) { // 尝试解析错误响应,若失败则使用状态文本 const errorInfo = await res.json().catch(() => ({ message: res.statusText })); throw new Error(errorInfo.message || 'Failed to load expenses'); } return res.json(); }; - 添加错误捕获逻辑
在视图层调用时添加catch,处理请求失败的情况:useEffect(() => { fetchExpenses() .then((res) => { // 区分数据和提示信息 if (res.message) { console.log(res.message); setExpenses([]); // 无数据时设置空数组 } else { setExpenses(res); } }) .catch((err) => { console.error('Fetch error:', err); // 可在此添加用户友好的错误提示,比如弹窗或页面提示 }); }, []);
内容的提问来源于stack exchange,提问作者vroque2022
相关产品推荐
相关产品推荐

