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

React JS重置密码请求返回400(Bad Request)错误排查求助

密码重置请求返回400 Bad Request的排查与修复

问题描述

我基于React实现了密码重置功能,流程为:用户提交邮箱后会收到包含token与邮箱的重置链接,页面通过useSearchParams获取链接中的email和token参数,发起POST请求至/api/accounts/reset-password接口完成密码重置。但控制台提示错误:

Failed to load resource: the server responded with a status of 400 (Bad Request)

我确认问题出在客户端,以下是我的代码:

import { useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import api from '../contexts/BaseUrl';

function ResetPassword(){
const [searchParams] = useSearchParams();
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [success, setSuccess] = useState(null);

const [errMsg, setErrMsg] = useState("")

const email = searchParams.get('email');
const token = searchParams.get('token');


const handleSubmit = async (e) => {
    e.preventDefault();
    try{
        const response = await api.post(
            '/api/accounts/reset-password', 
            JSON.stringify({password, confirmPassword, email, token}),
            {
                headers:{
                    "Accept" : "application/json",
                    "Content-Type" : "application/json",
                }
            });
     
        setPassword("");
        setConfirmPassword("");
        setSuccess(true);
    }catch(err){          
        setPassword("");
        setConfirmPassword("");
        setSuccess(false);
        if(!err?.response){
            setErrMsg('No Server Response')
        }else{
            setErrMsg('Failed changing password!');
        }
    }
    
}

return (  
     <div>
         <div>Email : {email}</div>
         <button onClick={() => console.log(tokenGet)}>Token</button>
         
                <form className="userContent2" 
                    onSubmit={handleSubmit}
                >
                

                <label>New Password: </label>
                <input
                    type="password"
                    pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$"
                    value = {password}
                    required
                    onChange={event => {
                        setPassword(event.target.value);
                     
                        if (event.target?.validity?.patternMismatch) {
                            event.target?.setCustomValidity('Min - 8 chars,1 Uppercase, 1 Lowercase, 1 number, 1 special character ');
                        } else {
                            event.target?.setCustomValidity('');
                        }
                    }}
                />
                <label>Confirm New Password: </label>
                <input
                    type="password"
                    pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$"
                    value = {confirmPassword}
                    required
                    onChange={event => {
                        setConfirmPassword(event.target.value);
                       
                        if (event.target?.value !== password) {
                            event.target?.setCustomValidity('Password doesn\'t match');
                        } else {
                            event.target?.setCustomValidity('');
                        }
                    }}
                />
                <button className='userButton'>Save</button>

                {!success && <div className='error'>{err}</div>}
                {success && <div className='success'>Password Successfully Changed!</div>}
            </form>
        
    </div>
    
 );}


 export default ResetPassword;

问题排查与修复点

  • 冗余请求参数触发后端校验失败
    密码确认是前端验证逻辑,后端重置接口通常只需要password、email、token三个参数。你传入的confirmPassword属于冗余参数,会触发后端参数校验返回400,需要从请求体中移除。

  • 不必要的JSON序列化导致格式异常
    如果你的api实例基于Axios创建,Axios会自动将JavaScript对象序列化为JSON请求体,手动调用JSON.stringify反而可能导致格式错误,直接传入对象即可。

  • 错误提示变量引用错误
    你定义的错误状态变量是errMsg,但渲染时用了未定义的err,导致错误信息无法显示,需修正为{errMsg},同时优化渲染逻辑,避免初始状态(success为null)时错误提示误显示。

  • 未提前拦截密码不一致的情况
    虽然输入框有自定义校验,但在提交前手动做一次密码一致性检查,能提前拦截错误,减少无效请求。

  • 变量拼写错误
    页面中的按钮点击事件用了未定义的tokenGet,需改为已定义的token,避免控制台出现额外错误。

修改后的关键代码示例

修正后的handleSubmit函数

const handleSubmit = async (e) => {
    e.preventDefault();
    
    // 前端提前校验密码一致性
    if (password !== confirmPassword) {
        setErrMsg('两次输入的密码不一致');
        return;
    }

    try{
        const response = await api.post(
            '/api/accounts/reset-password', 
            {password, email, token}, // 移除confirmPassword,无需手动序列化
            {
                headers:{
                    "Accept" : "application/json",
                    "Content-Type" : "application/json",
                }
            });
     
        setPassword("");
        setConfirmPassword("");
        setSuccess(true);
        setErrMsg("");
    }catch(err){          
        setPassword("");
        setConfirmPassword("");
        setSuccess(false);
        if(!err?.response){
            setErrMsg('无服务器响应')
        }else{
            // 尝试获取后端返回的具体错误信息,提升调试效率
            setErrMsg(err.response.data?.message || '密码修改失败!');
        }
    }
}

修正后的错误提示渲染

{success === false && <div className='error'>{errMsg}</div>}
{success === true && <div className='success'>密码修改成功!</div>}

修正后的Token按钮

<button onClick={() => console.log(token)}>查看Token</button>

内容的提问来源于stack exchange,提问作者Ehtesam Fayek Utsho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 17:50:25