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

PUT 400(Bad Request)故障排查:商品库存更新功能异常求助

解决React+Node.js库存更新400 Bad Request问题

核心问题分析

你的代码存在多处参数不匹配、校验逻辑错误和SQL逻辑错误,直接导致400请求失败,具体如下:

  • 前后端路由参数名完全不符,后端拿到的参数不是预期值
  • 后端校验逻辑同时要求两个互斥参数合法,必然触发校验失败
  • SQL更新条件错误,会批量修改所有库存匹配的商品,而非指定商品
  • 前端参数有效性判断逻辑写反,未正确校验productID

修复代码

前端dashboard.jsx修改

const Dashboard = () => {
  const [productStocks, setProductStocks] = useState([]);

  const handleUpdateStock = (
    productID,
    productStock,
    quantityToAdd,
    quantityToRemove
  ) => {
    // 优先校验productID有效性
    if (productID === undefined || isNaN(productID)) {
      console.error('productID无效');
      return;
    }
    
    // 统一转换为数字类型,避免字符串传参问题
    const body = quantityToAdd !== undefined ? 
      { quantityToAdd: Number(quantityToAdd) } : 
      { quantityToRemove: Number(quantityToRemove) };

    fetch(`http://localhost:8081/updateStock/${productID}`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(body),
    })
      .then((response) => {
        if (!response.ok) {
          throw new Error(`HTTP错误! 状态码: ${response.status}`);
        }
        return response.json();
      })
      .then((data) => {
        console.log('更新响应:', data);
        setProductStocks((prevProductStocks) => {
          const updatedProductIndex = prevProductStocks.findIndex(
            (product) => product.productID === productID
          );
          // 处理找不到商品的边界情况
          if (updatedProductIndex === -1) return prevProductStocks;
          
          const updatedProductStocks = [...prevProductStocks];
          updatedProductStocks[updatedProductIndex] = {
            ...updatedProductStocks[updatedProductIndex],
            productStock: data.updatedStock,
          };
          return updatedProductStocks;
        });
      })
      .catch((error) => console.error('库存更新失败', error));
  };

  return (
    <div className='div1'>
      <h1>商品库存</h1>
      <ul>
        {productStocks.map((product) => (
          <li key={product.productID}> {/* 用唯一productID作为key更可靠 */}
            <strong>ID:</strong> {product.productID}, 
            <strong>名称:</strong> {product.productName}, 
            <strong>库存:</strong> {product.productStock}
            <button onClick={() => handleUpdateStock(product.productID, product.productStock, 1)}>
              <MdAdd className="add-icon" />
            </button>
            <button onClick={() => handleUpdateStock(product.productID, product.productStock, undefined, 1)}>
              <MdRemove className="remove-icon" />
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
};

后端app.js修改

app.put('/updateStock/:productID', (req, res) => {
  const { quantityToAdd, quantityToRemove } = req.body;
  const productID = req.params.productID;

  console.log('收到PUT请求:', req.body);

  // 校验productID是否为正整数
  if (isNaN(productID) || Number(productID) <= 0) {
    return res.status(400).json({ error: '无效的商品ID,必须是正整数。' });
  }

  // 按需校验传入的数量参数
  let updateAmount;
  if (quantityToAdd !== undefined) {
    if (isNaN(quantityToAdd) || Number(quantityToAdd) < 0) {
      return res.status(400).json({ error: '无效的新增数量,必须是非负整数。' });
    }
    updateAmount = `+ ${Number(quantityToAdd)}`;
  } else if (quantityToRemove !== undefined) {
    if (isNaN(quantityToRemove) || Number(quantityToRemove) < 0) {
      return res.status(400).json({ error: '无效的减少数量,必须是非负整数。' });
    }
    updateAmount = `- ${Number(quantityToRemove)}`;
  } else {
    return res.status(400).json({ error: '必须传入quantityToAdd或quantityToRemove参数。' });
  }

  // 参数化SQL查询,避免注入风险,用productID定位唯一商品
  const updateQuery = `
    UPDATE product 
    SET productStock = GREATEST(0, productStock ${updateAmount})
    WHERE productID = ?`;

  db.query(updateQuery, [productID], (err, result) => {
    if (err) {
      console.error('库存更新失败:', err.message);
      return res.status(500).json({ error: '服务器内部错误', details: err.message });
    }

    // 查询更新后的最新库存
    const selectQuery = 'SELECT productID, productName, productStock FROM product WHERE productID = ?';
    db.query(selectQuery, [productID], (err, updatedResult) => {
      if (err) {
        console.error('获取更新后库存失败:', err.message);
        return res.status(500).json({ error: '服务器内部错误', details: err.message });
      }
      if (updatedResult.length === 0) {
        return res.status(404).json({ error: '未找到指定商品。' });
      }
      return res.json({ 
        success: true, 
        message: '库存更新成功。', 
        updatedStock: updatedResult[0].productStock 
      });
    });
  });
});

测试步骤

  1. POSTMAN测试:发送PUT请求到http://localhost:8081/updateStock/1,请求体传入{"quantityToAdd":1}或{"quantityToRemove":1},验证返回状态和数据
  2. 前端测试:点击增减按钮后,查看控制台日志,确认库存是否实时更新

内容的提问来源于stack exchange,提问作者Kristian Diaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 00:37:06