Next.js 13与Sanity.io中POST请求报错问题求助
问题分析与解决方案
核心错误原因
- Sanity Mutation格式错误:你当前的请求体直接传了用户文档对象,但Sanity v2021-10-21版本的mutate API要求必须用
mutations数组包裹,每个元素是具体的create操作。 - API路由未处理错误:你直接
awaitSanity请求但没检查响应状态,哪怕Sanity请求失败,仍会返回成功给前端,导致前端无法获取真实错误信息。 - Next.js API类型错误:
request参数应该是NextRequest而非Response,且需导入NextResponse才能正确返回响应。 - 前端无错误捕获:提交函数没有用
try/catch包裹异步操作,报错直接抛出后没有友好处理逻辑。
修正后的API路由代码
import { NextRequest, NextResponse } from 'next/server'; export async function POST(request: NextRequest) { // 确保这三个环境变量已在.env.local中正确配置 const { projectId, dataset, sanity_API_Token } = process.env; try { const { firstName, surname, email, phone, password } = await request.json(); const sanityResponse = await fetch(`https://${projectId}.api.sanity.io/v2021-10-21/data/mutate/${dataset}`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${sanity_API_Token}`, }, body: JSON.stringify({ mutations: [ { create: { _type: 'user', firstName, surname, email, phone, password // 注意:明文存密码极度不安全,建议先哈希处理 } } ] }), }); if (!sanityResponse.ok) { const errorData = await sanityResponse.json(); throw new Error(`Sanity请求失败: ${JSON.stringify(errorData)}`); } return NextResponse.json({ message: '添加成功' }); } catch (error) { console.error('注册接口错误:', error); return NextResponse.json({ error: '注册失败' }, { status: 500 }); } }
修正后的前端提交函数
import { useState } from 'react'; const Register = () => { const [firstName, setFirstName] = useState(""); const [surname, setSurname] = useState(""); const [email, setEmail] = useState(""); const [phone, setPhone] = useState(""); const [password, setPassword] = useState(""); const [errorMessage, setErrorMessage] = useState(""); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setErrorMessage(""); try { const response = await fetch("/api/register", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ firstName, surname, email, phone, password }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || "提交表单失败"); } // 注册成功后的逻辑,比如跳转或提示 alert("注册成功"); } catch (err) { if (err instanceof Error) { setErrorMessage(err.message); } else { setErrorMessage("未知错误"); } } }; return ( <form onSubmit={handleSubmit}> {/* 这里添加你的表单输入元素,比如firstName输入框等 */} {errorMessage && <p style={{color: 'red'}}>{errorMessage}</p>} <button type="submit">注册</button> </form> ); }; export default Register;
额外注意事项
- 密码安全:绝对不要明文存储用户密码,建议在前端或后端用bcrypt等工具哈希后再存入Sanity。
- 环境变量验证:确认
projectId、dataset、sanity_API_Token已正确配置,且API Token拥有写入权限。 - Sanity Schema检查:确保你的Sanity Schema中存在
user类型,且firstName、surname等字段的定义与提交的数据类型匹配(比如是否允许字符串、是否为必填项)。
内容的提问来源于stack exchange,提问作者Rengkat
相关产品推荐
相关产品推荐

