Next.js发起POST请求调用更新地址API返回无效JSON报错
问题根源
错误出在请求体的传参方式,和你构造的对象结构本身无关:
- 当你在fetch请求头里设置
Content-Type: application/json时,body字段必须传入经过JSON.stringify()序列化后的JSON字符串,你直接传入了原生JS数组,fetch不会自动帮你做JSON序列化,最终发出去的请求体是调用toString()生成的无效字符串[object Object] - 后端收到完全不符合JSON格式的请求体,解析失败后会返回纯文本/HTML格式的错误响应,不是约定的JSON结构,前端调用
res.json()解析响应时就会触发无效JSON报错 - 你在控制台打印的是自己构造的原生JS对象,不是实际通过网络发出的请求内容,所以会误以为格式正确
- 额外的逻辑问题:你当前的表单校验逻辑检测到空字段后只弹出提示,没有终止函数执行,空字段依然会发起请求;另外代码里多写了一层无意义的数组包裹,和你打印的请求结构也不匹配,
JSON.parse(JSON.stringify())的深拷贝操作在这里完全多余。
修复步骤
- 表单校验检测到空字段后直接终止提交逻辑,不要继续执行后续请求
- 去掉无意义的深拷贝、多余数组包裹逻辑
- 用
JSON.stringify()序列化请求体后再传给body字段 - 解析响应前先判断接口响应状态,遇到错误时先读取纯文本内容方便排查,避免直接解析JSON报错
修复后的核心代码如下:
async function handleSubmit() { const data = { deliveryAddress, landmark, pincode, district, block, state } const userID = localStorage.getItem("userID") // 表单校验 let hasEmptyField = false for (let item in data) { const element = data[item]; if (element.trim() === "") { toast.error(`${item} field must be filled`, { position: "top-center", autoClose: 3000, hideProgressBar: false, closeOnClick: true, pauseOnHover: true, draggable: true, progress: undefined }); hasEmptyField = true break; } } // 有空字段直接终止 if (hasEmptyField) return const requestPayload = { address: data, userid: userID } try { const res = await fetch(`${process.env.NEXT_PUBLIC_HOST}/api/updateaddress`, { method: "POST", headers: { "Content-Type": "application/json" }, // 核心修复:序列化JSON字符串 body: JSON.stringify(requestPayload) }) // 先判断响应状态 if (!res.ok) { const errorContent = await res.text() console.log("接口异常返回内容:", errorContent) return } const parsedResponse = await res.json() console.log("response", parsedResponse); } catch (error) { console.log(error) } }
额外排查提示
如果修复后依然报错,可以在浏览器开发者工具的「网络」面板里找到这个updateaddress请求,查看「请求载荷」 tab 下实际发送的内容,以及「响应」tab下后端返回的原始内容,就能直接定位是请求格式问题还是后端返回格式问题。
内容的提问来源于stack exchange,提问作者Veer-Khatri
相关产品推荐
相关产品推荐

