React+Spring登录页Axios请求本地PostgreSQL遇CORS及404错误
登录功能Axios请求错误排查与修复
问题背景
开发React+Spring个人项目,实现登录页功能,需验证用户输入的邮箱和密码是否存在于PostgreSQL数据库(DataGrip管理)。暂未使用JWT,采用简化实现方式,但使用Axios发起请求时出现错误。
现有React登录页代码
import React, {useEffect, useState} from 'react'; import TextField from '@mui/material/TextField'; import Container from '@mui/material/Container'; import { Paper } from '@mui/material'; import Button from '@mui/material/Button'; import axios from 'axios' export default function BasicTextFieldslLogin() { const paperStyle={padding:'50px 20px', width:'600', margin:'20px auto'}; const[email, setEmail] = useState('') const[password, setPassword] = useState('') const[posts, setPosts] = useState([]) const handleClick = (e)=>{ const person = {email, password} console.log(person) } useEffect(()=>{ axios.get("http://localhost:8080/persons/login/{email}/{password}") .then(res=>{ console.log(res) setPosts(res.data) console.log(posts) }) .catch(err=>{ console.log(err) }) },[]) return ( <Container> <Paper elevation={3} style={paperStyle}> <h1 style={{color:"blue"}}>Login!</h1> <form className="formLogin" noValidate autoComplete="off"> <TextField sx = {{mb: 2}} required id="outlined-basic" label="Email" variant="outlined" fullWidth value = {email} onChange = {(e)=>setEmail(e.target.value)} /> <TextField sx = {{mb: 2}} required id="outlined-basic" label="Password" type="password" variant="outlined" fullWidth value = {password} onChange = {(e)=>setPassword(e.target.value)} /> <Button variant="contained" sx={{width:"200px", height:"50px", fontSize:"30px", fontWeight:"bold"}} onClick={handleClick} >Submit</Button> </form> </Paper> </Container> ); }
报错信息
从源'http://localhost:3000'访问XMLHttpRequest at 'http://localhost:8080/persons/login/%7Bemail%7D/%7Bpassword%7D'已被CORS策略阻止:请求的资源上不存在'Access-Control-Allow-Origin'头。
AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
code: "ERR_NETWORK"
message: "Network Error"GET http://localhost:8080/persons/login/%7Bemail%7D/%7Bpassword%7D net::ERR_FAILED 404
修复方案
1. 修正请求路径与触发时机
- 原代码中
useEffect在页面加载时就发起请求,且URL中的{email}/{password}是硬编码字符串,未替换为用户输入的实际值。 - 应将请求逻辑移至
handleClick函数(点击Submit按钮时触发),并使用模板字符串拼接参数:
const handleClick = (e)=>{ e.preventDefault(); // 阻止表单默认提交行为 const person = {email, password}; // 使用模板字符串替换参数 axios.get(`http://localhost:8080/persons/login/${email}/${password}`) .then(res=>{ console.log(res); setPosts(res.data); }) .catch(err=>{ console.log(err); }); } // 移除页面加载时的无效请求 // useEffect(()=>{...},[])
2. 解决CORS跨域问题
Spring后端需配置允许跨域请求:
- 方法1:添加@CrossOrigin注解
在处理登录请求的Controller方法上添加注解,允许React前端域名访问:@CrossOrigin(origins = "http://localhost:3000") @GetMapping("/persons/login/{email}/{password}") public ResponseEntity<?> login(@PathVariable String email, @PathVariable String password) { // 数据库验证逻辑 } - 方法2:全局CORS配置
若多个接口需要跨域,可添加全局配置类:@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:3000") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*"); } }
3. 优化请求方式(推荐)
登录请求不建议使用GET(密码会暴露在URL中),改用POST方法传递参数:
- React端修改:
const handleClick = (e)=>{ e.preventDefault(); const person = {email, password}; axios.post("http://localhost:8080/persons/login", person) .then(res=>{ console.log(res); setPosts(res.data); }) .catch(err=>{ console.log(err); }); } - Spring端对应修改为
@PostMapping,接收请求体参数:@CrossOrigin(origins = "http://localhost:3000") @PostMapping("/persons/login") public ResponseEntity<?> login(@RequestBody Person person) { // 验证email和password的逻辑 }
内容的提问来源于stack exchange,提问作者Mihai Daian
相关产品推荐
相关产品推荐

