Next.js中Axios调用API路由返回404错误的排查求助
Next.js Axios GET请求404错误排查与修复方案
一、先确认请求的实际有效性
在create.js的getParentData函数中添加日志,打印完整请求URL,同时通过浏览器开发者工具的Network面板查看实际发送的请求地址:
const getParentData = async () => { console.log(`请求URL: /api/product/${product.parent}`); // 打印请求地址 // ... 原有逻辑 };
重点确认:
- 路径拼写是否与API路由文件匹配(比如是否应为
/api/products/[id]而非/api/product/[id]) product.parent是否为有效的MongoDB ObjectId,避免空值或无效ID导致URL变成/api/product/这种无效路径
二、检查API路由的位置与命名
Next.js的API路由严格遵循pages/api目录的结构:
- 确保
[id].js确实放在pages/api/product/目录下,没有拼写错误(比如误写为products复数) - 文件名的括号必须是英文半角的
[id].js,不能是中文或全角符号
三、修复API路由的错误处理逻辑
当前pages/api/product/[id].js存在漏洞:如果Product.findById(id)未找到产品,product会是null,后续访问product.subProducts会直接报错,但catch块返回的是500状态码,无法正确反馈“产品不存在”的情况。修改代码:
handler.get(async (req, res) => { try { db.connectDb(); const id = req.query.id; const style = req.query.style || 0; const size = req.query.size || 0; // 先判断产品是否存在 const product = await Product.findById(id).lean(); if (!product) { db.disconnectDb(); return res.status(404).json({ message: "产品不存在" }); } let discount = product.subProducts[style].discount; let priceBefore = product.subProducts[style].sizes[size].price; let price = discount ? priceBefore - priceBefore / discount : priceBefore; db.disconnectDb(); return res.json({ _id: product._id, style: Number(style), name: product.name, description: product.description, slug: product.slug, sku: product.subProducts[style].sku, brand: product.brand, category: product.category, subCategories: product.subCategories, shipping: product.shipping, images: product.subProducts[style].images, color: product.subProducts[style].color, size: product.subProducts[style].sizes[size].size, price, priceBefore, quantity: product.subProducts[style].sizes[size].qty, }); } catch (error) { db.disconnectDb(); // 确保错误场景下也断开数据库连接 return res.status(500).json({ message: error.message }); } });
四、优化前端请求触发逻辑
当前useEffect依赖product.parent,当product.parent为空字符串时也会发起无效请求,触发404。添加判断,仅当product.parent有有效值时才请求:
useEffect(() => { const getParentData = async () => { // 空值直接返回,避免无效请求 if (!product.parent) return; try { const { data } = await axios.get(`/api/product/${product.parent}`); setProduct({ ...product, name: data.name, description: data.description, brand: data.brand, category: data.category, subCategories: data.subCategories, questions: [], details: [], }); } catch (err) { console.error("获取父产品失败:", err.response?.data?.message || err.message); } }; getParentData(); }, [product.parent]);
五、其他排查点
- 修改API路由后重启Next.js开发服务器,确保新代码生效
- 确认MongoDB数据库中存在该ID对应的产品文档
- 检查
db.connectDb()是否正确建立了数据库连接,可以在API路由中添加日志验证
内容的提问来源于stack exchange,提问作者Milad Hossainie - KAKA SHEX
相关产品推荐
相关产品推荐

