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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:11:32