使用Fetch API PUT请求更新图书评分时遇404错误求助
解决json-server中PUT请求404错误的问题
嘿,我来帮你搞定这个404错误!这在使用json-server搭建伪API的时候是个很常见的小问题,咱们一步步来排查和修复。
错误原因分析
1. PUT请求的URL不符合json-server的REST规范
json-server遵循标准的REST API规则,更新单个资源必须指定该资源的ID,也就是请求URL应该是/books/:id(比如localhost:3001/books/0对应ID为0的图书)。你现在直接请求localhost:3001/books,json-server根本不知道你要更新哪本书,自然会返回404。而且你把整个Books数组作为请求体发送,这也不符合单个资源更新的要求。
2. 代码里的计算逻辑和字段名错误
- 你在计算新评分的时候重复加了用户提交的rating:
let newRating = (parseInt(obj.points) + parseInt(rating)) / parseFloat(obj.total);,但前面已经执行了newPts = parseInt(obj.points) + parseInt(rating),这里再重复加rating会导致评分计算严重错误。 - 你把更新的字段写成了
obj.ratings,但你的JSON数据里的字段是rating,字段名不匹配会导致更新后的数据不正确。
修复步骤和代码
1. 定位要更新的图书,记录它的ID
在遍历Books数组的时候,除了更新字段,还要把更新后的图书对象保存下来,这样才能构造正确的PUT请求URL。
2. 修正评分计算和字段名
去掉重复加rating的逻辑,把obj.ratings改成obj.rating,确保和JSON数据的字段一致。
3. 发送针对单个图书的PUT请求
用获取到的图书ID构造正确的URL,并且只把更新后的单个图书对象作为请求体发送。
下面是修改后的完整代码:
export const postRatings = (Books, title, rating) => (dispatch) => { let updatedBook = null; Books.some(function(obj){ if(obj.title === title) { // 更新总评分人数 obj.total = parseInt(obj.total) + 1; // 更新总分数 const newPts = parseInt(obj.points) + parseInt(rating); obj.points = newPts.toString(); // 计算新评分(不再重复加rating) const newRating = newPts / obj.total; // 修正字段名并保留一位小数 obj.rating = newRating.toFixed(1); updatedBook = {...obj}; // 复制更新后的图书对象,避免引用问题 return true; } }); // 确保找到要更新的图书再发送请求 if (updatedBook) { // 注意:建议加上http://协议,避免部分环境下请求失败 fetch(`http://localhost:3001/books/${updatedBook.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(updatedBook) // 仅发送单个更新后的图书对象 }) .then(response => { if(response.ok) { return response.json(); // 正确解析返回的JSON数据 } else { const error = new Error(`Error ${response.status}: ${response.statusText}`); error.response = response; throw error; } }) .then(updatedData => { console.log("Updated book data:", updatedData); alert("Rating Added!"); // 这里可以dispatch一个action来更新本地的Books状态,保持前后端数据一致 // dispatch(updateBookInState(updatedData)); }) .catch(error => { console.error('Error Message:', error.message); alert(`Some Problem Occurred.\nError: ${error.message}`); }); } else { alert("Book not found!"); } }
额外提示
json-server的核心REST规则你可以记一下,避免再踩类似的坑:
GET /books:获取所有图书GET /books/:id:获取单本指定ID的图书POST /books:新增一本图书PUT /books/:id:更新指定ID的图书DELETE /books/:id:删除指定ID的图书
内容的提问来源于stack exchange,提问作者Keval Dhanani
相关产品推荐
相关产品推荐

