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> ); };
关键修改说明
- 添加
event.preventDefault(),确保请求在页面不刷新的情况下完成 - 删除组件内重复的Axios导入语句,统一使用顶部的
import - 修复错误处理逻辑,保留原始错误信息用于排查
- 移除Button的
onClick绑定,避免重复触发请求 - 直接使用组件状态中的用户输入值,替换硬编码的测试凭证
- 简化数据传递方式,利用Axios自动序列化功能
内容的提问来源于stack exchange,提问作者eyilink
相关产品推荐
相关产品推荐

