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

React前端调用ASP.NET重置密码API时出现400 Bad Request错误

问题分析与解决方案

后端通过Swagger测试重置密码邮件功能正常,但React前端调用POST https://localhost:7079/api/Account/forgot-password时返回400 Bad Request,更换为axios后问题依旧。结合代码和常见问题,可能的原因及解决方法如下:

可能的原因及修复步骤

1. 请求参数字段名与后端不匹配

ASP.NET Core的模型绑定默认对大小写敏感,如果后端接收模型的字段名为Email(首字母大写),而前端传的是小写email,后端无法正确绑定参数,会返回400错误。

修复代码:
修改axios请求的参数名,与后端保持一致:

const response = await axios.post('https://localhost:7079/api/Account/forgot-password', {
  Email: email, // 将字段名改为后端期望的名称,比如首字母大写
});

2. 显式指定Content-Type请求头

虽然axios默认会为JSON请求设置Content-Type: application/json,但某些环境下可能丢失该头,导致后端无法解析请求体。

修复代码:
添加请求头配置:

const response = await axios.post('https://localhost:7079/api/Account/forgot-password', {
  email: email, // 或对应正确的字段名
}, {
  headers: {
    'Content-Type': 'application/json'
  }
});

3. 清理输入值

用户输入的邮箱可能包含前后空格,导致后端验证失败。在发送请求前先修剪空格:

修复代码:

const sendEmail = async (e) => {
  e.preventDefault();
  const trimmedEmail = email.trim(); // 修剪空格
  if (trimmedEmail === '') {
    setShowError(false);
    setMessageFromServer('');
    setShowNullError(true);
  } else {
    try {
      const response = await axios.post('https://localhost:7079/api/Account/forgot-password', {
        Email: trimmedEmail, // 使用修剪后的值
      });
      // ... 后续逻辑
    } catch (error) {
      // ... 错误处理
    }
  }
};

4. 查看完整错误详情

在前端错误捕获中打印完整的响应信息,获取后端返回的具体错误提示,比如“Email字段为必填项”:

修复代码:

catch (error) {
  console.error('完整错误响应:', error.response); // 打印整个响应对象
  if (error.response?.data === 'email not in db') {
    setShowError(true);
    setMessageFromServer('');
    setShowNullError(false);
  } else {
    // 处理其他400错误,比如参数验证失败
    setShowError(true);
    setMessageFromServer(error.response?.data?.message || '请求格式错误');
  }
}

完整修改后的前端代码

import React, { useState } from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';

const title = 'Forgot Password Screen';

function ForgotPassword() {
  const [email, setEmail] = useState('');
  const [showError, setShowError] = useState(false);
  const [messageFromServer, setMessageFromServer] = useState('');
  const [showNullError, setShowNullError] = useState(false);

  const handleChange = (event) => {
    setEmail(event.target.value);
  };

  const sendEmail = async (e) => {
    e.preventDefault();
    const trimmedEmail = email.trim();
    if (trimmedEmail === '') {
      setShowError(false);
      setMessageFromServer('');
      setShowNullError(true);
    } else {
      try {
        const response = await axios.post(
          'https://localhost:7079/api/Account/forgot-password',
          { Email: trimmedEmail }, // 匹配后端字段名
          { headers: { 'Content-Type': 'application/json' } }
        );
        if (response.data === 'recovery email sent') {
          setShowError(false);
          setMessageFromServer('recovery email sent');
          setShowNullError(false);
        }
      } catch (error) {
        console.error('完整错误响应:', error.response);
        if (error.response?.data === 'email not in db') {
          setShowError(true);
          setMessageFromServer('');
          setShowNullError(false);
        } else {
          setShowError(true);
          setMessageFromServer(error.response?.data?.message || '请求格式错误,请检查输入');
        }
      }
    }
  };

  return (
    <div className="py-10 flex flex-col items-center">
      <h2 className="text-2xl font-semibold mb-4">{title}</h2>
      <form className="profile-form" onSubmit={sendEmail}>
        <input
          style={{ width: '100%' }}
          id="email"
          type="email" // 添加email类型,触发浏览器基础验证
          value={email}
          onChange={handleChange}
          placeholder="Email Address"
        />
        <button className="btn btn-primary mt-4 w-full">
          Send Password Reset Email
        </button>
      </form>
      {showNullError && (
        <p className="text-red-600 mt-4">The email address cannot be null.</p>
      )}
      {showError && (
        <div className="mt-4">
          <p>
            {messageFromServer || "That email address isn't recognized. Please try again or register for a new account."}
          </p>
          <Link to="/register" className="inline-block mt-2 text-primary underline cursor-pointer">
            Register
          </Link>
        </div>
      )}
      {messageFromServer === 'recovery email sent' && (
        <div className="mt-4">
          <h3>Password Reset Email Successfully Sent!</h3>
        </div>
      )}
      <Link to="/" className="btn btn-primary mt-4 w-full">
        Go Home
      </Link>
    </div>
  );
}

export default ForgotPassword;

内容的提问来源于stack exchange,提问作者Moses Otieno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:54:54