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

React中Axios调用Heroku托管的Express登录API失败求助

React中Axios调用Heroku登录API失败的解决方案

问题根源

Postman请求正常但React调用失败,问题出在代码的几个细节上,以下是针对性修复方案:

核心问题点及修复

  • 未阻止表单默认提交行为:表单提交后会触发页面刷新,直接中断Axios请求
  • 重复导入Axios:顶部已import,组件内又用require引入,造成实例冲突
  • 错误处理覆盖原始信息:catch中把error重置为新Error,丢失关键排查日志
  • 重复触发请求:Button同时绑定onClick和Form的onSubmit,导致请求执行两次
  • 不必要的JSON序列化:Axios可自动处理对象转JSON,无需手动调用JSON.stringify

修正后完整代码

import React, { useState } from "react";
import './Login.css';
import { FaMountain } from 'react-icons/fa';
import { Form, Button } from "react-bootstrap";
import axios from "axios";
import Cookies from "universal-cookie";

const cookies = new Cookies();

export const Login = () => {
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [login, setLogin] = useState(false);
    const [state, setState] = useState(false);

    const handleSubmit = (event) => {
        // 阻止表单默认刷新行为
        event.preventDefault();

        const config = {
            method: "post",
            url: "https://nodejs-mongodb-authapp.herokuapp.com/login",
            headers: {
                "Content-Type": "application/json",
            },
            // 直接传递状态对象,Axios自动处理序列化
            data: {
                email: email,
                password: password
            },
        };

        axios(config)
            .then((result) => {
                alert("登录成功");
                setLogin(true);
                cookies.set("TOKEN", result.data.token, {
                    path: "/",
                });
                // 若使用路由导航,请确保已导入useNavigate钩子
                // navigate('/auth');
            })
            .catch((error) => {
                // 保留原始错误信息,便于排查问题
                console.error("登录失败:", error.response?.data || error.message);
                alert("登录失败,请查看控制台日志");
            });
    };

    return (
        <div className="p1">
            <div className="log">
                <form className="formFields">
                    <div className="lfa">
                        <FaMountain />
                    </div>
                    <p>LOG IN</p>

                    <Form onSubmit={handleSubmit} className="form_">
                        <Form.Group controlId="formBasicEmail">
                            <Form.Control
                                type="email"
                                name="email"
                                value={email}
                                onChange={(e) => setEmail(e.target.value)}
                                placeholder="Enter email"
                            />
                        </Form.Group>

                        <Form.Group controlId="formBasicPassword">
                            <Form.Control
                                type="password"
                                name="password"
                                value={password}
                                onChange={(e) => setPassword(e.target.value)}
                                placeholder="Password"
                            />
                        </Form.Group>

                        {/* 移除重复的onClick绑定,仅通过Form的onSubmit触发请求 */}
                        <Button
                            variant="primary"
                            type="submit"
                        >
                            Login
                        </Button>
                    </Form>
                </form>
            </div>
            {login ? (
                <p className="text-success">登录成功</p>
            ) : (
                <p className="text-danger">未登录</p>
            )}
        </div>
    );
};

关键修改说明

  1. 添加event.preventDefault(),确保请求在页面不刷新的情况下完成
  2. 删除组件内重复的Axios导入语句,统一使用顶部的import
  3. 修复错误处理逻辑,保留原始错误信息用于排查
  4. 移除Button的onClick绑定,避免重复触发请求
  5. 直接使用组件状态中的用户输入值,替换硬编码的测试凭证
  6. 简化数据传递方式,利用Axios自动序列化功能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:36:14