NextJS开发登录系统时遭遇AxiosError: ERR_BAD_REQUEST错误求助
问题:NextJS注册系统持续触发Axios 400错误
AxiosError {message: 'Request failed with status code 400', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
相关代码片段
客户端(RegisterPage)
const [authState, setAuthState] = useState({ name: "", email: "", password: "", password_confirmation: "", }); const [loading, setLoading] = useState<boolean>(false); const [errors, setErrors] = useState<registerErrorType>({}); const submitForm = () => { setLoading(true); axios .post("http://localhost:3000/api/auth/register", authState) .then((res) => { setLoading(false); const response = res?.data; // debugger; if (response?.status == 200) { console.log("User created successfully"); } else if (response?.status == 400) { setErrors(response?.errors); } }) .catch((error: any) => { console.error("Axios request error:", error); setLoading(false); }); };
服务端(RegisterPage API)
export async function POST(request: NextRequest) { try { const body = await request.json(); const validator = vine.compile(registerSchema); const output = await validator.validate(body); validator.errorReporter = () => new ErrorReporter(); // check if email already existes const user = await User.findOne({ email: output.email }); if (user) { return NextResponse.json( { status: 400, errors: { email: "Email is already exists", }, }, { status: 200 } ); } else { // Encrypt the password const salt = bcrypt.genSaltSync(10); output.password = bcrypt.hashSync(output.password, salt); await User.create(output); return NextResponse.json( { status: 200, message: "User created successfully" }, { status: 200 } ); } } catch (error) { if (error instanceof errors.E_VALIDATION_ERROR) { return NextResponse.json( { status: 400, errors: error.messages }, { status: 400 } ); } } }
问题排查与修复
1. 响应状态码不匹配导致Axios进入catch
当邮箱已存在时,服务端返回的HTTP状态码是200,但响应体status字段设为400。Axios以HTTP状态码判断请求是否成功,非2xx状态码会直接进入catch块,无法走到then内的错误处理逻辑。
修复:将邮箱已存在的响应状态码改为400,与响应体字段保持一致:
if (user) { return NextResponse.json( { status: 400, errors: { email: "Email already exists", // 修正语法错误 }, }, { status: 400 } // 把200改为400 ); }
2. Vine验证器配置顺序错误
先执行validator.validate(body)再设置errorReporter,会导致自定义错误报告器不生效,验证失败时抛出的错误不符合预期。
修复:调整顺序,先配置错误报告器再执行验证:
const validator = vine.compile(registerSchema); validator.errorReporter = () => new ErrorReporter(); // 移到validate之前 const output = await validator.validate(body);
3. 未处理兜底异常
服务端catch块仅处理E_VALIDATION_ERROR,其他异常(如数据库连接失败)会导致函数无返回值,NextJS默认返回500状态码,同样触发Axios错误。
修复:添加兜底返回逻辑:
catch (error) { if (error instanceof errors.E_VALIDATION_ERROR) { return NextResponse.json( { status: 400, errors: error.messages }, { status: 400 } ); } // 处理其他未捕获异常 return NextResponse.json( { status: 500, errors: { server: "Internal server error" } }, { status: 500 } ); }
4. 客户端错误处理优化
当前客户端仅在响应体status为400时设置错误,但服务端返回HTTP 400时会直接进入catch,需在catch内提取服务端错误信息:
.catch((error: any) => { console.error("Axios request error:", error); setLoading(false); // 提取服务端返回的错误 if (error.response?.data?.errors) { setErrors(error.response.data.errors); } else { setErrors({ server: error.message || "Request failed" }); } });
内容的提问来源于stack exchange,提问作者Perdente
相关产品推荐
相关产品推荐

