React登录功能遇CORS跨域错误,请求排查原因及代码建议
问题描述
我正在用React.js开发一个支持邮箱密码登录的系统,后端REST API由客户提供。调用登录接口时遇到了CORS错误,不确定是客户给的API URL有问题,还是需要客户调整后端的CORS配置,同时也请帮忙检查我的前端代码是否存在问题。
错误信息
Access to XMLHttpRequest at 'https://login.xxx.com/login' from origin 'http://localhost:3002' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
完整前端代码
import React, { useState, useEffect, useRef } from 'react'; import { useCookies } from 'react-cookie'; import axios from 'axios'; import { useForm } from "react-hook-form"; import { useHistory } from 'react-router-dom'; import { apiURL } from './Default'; import logo_image from "../images/logo/logo.png"; import { useParams, Link } from 'react-router-dom' import { useDispatch } from "react-redux"; import background from "../images/background/BG.png"; import '../App.css'; import { isLoggedInOn } from "../stores/user"; import { setUserID } from "../stores/user"; const Login = () => { const history = useHistory(); const dispatch = useDispatch(); const [cookies, setCookie] = useCookies(); const { register, handleSubmit, watch, errors } = useForm(); const getJwt = async (data) =>{ console.log(data) await axios.post(`https://login.xxx.com/login`, { username:data.email, password:data.password, }, ) .then(function (response) { console.log(response.data.access) setCookie('accesstoken', response.data.access, { path: '/' }, { httpOnly: true }); setCookie('refreshtoken', response.data.refresh, { path: '/' }, { httpOnly: true }); dispatch(isLoggedInOn()); history.push('/'); }) .catch(err => { console.log("miss"); alert("Email or Password is wrong!"); }); }; return ( <div className="container"> <div className="row mx-auto"> <div className="col-md-4 mx-auto text-center"> <div className="row mx-auto logo_image"> <img className="" src={logo_image} alt="" /> </div> <div className="login-block"> <form onSubmit={handleSubmit(getJwt)}> <input placeholder='Email Address' className='form-control' {...register('email')} /> <input placeholder='Password' className='form-control' type="password" {...register('password', { required: true })} /> <Link to={`/`} style={{color: "white"}}>Reset password</Link><br></br> <input className='btn btn-block btn-primary col-12' type="submit" value="Login" /> </form> </div> <div className="register-block"> <p style={{color: "white"}}>Don't have an account yet?</p> <Link to={`/signup`} className='btn btn-secondary col-12'>Register</Link> </div> </div> </div> </div> ); } export default Login;
问题分析与解决方案
1. 核心问题:后端CORS配置缺失
从错误信息可以明确,问题出在后端未配置正确的CORS响应头。浏览器的同源策略阻止前端(http://localhost:3002)向不同源的后端(https://login.xxx.com)发起请求,因为后端返回的响应中没有包含Access-Control-Allow-Origin头。
这和API URL是否正确无关——如果URL错误,你会收到404这类请求错误,而非CORS报错。
2. 需要客户调整的后端配置
请让客户在后端服务中添加以下CORS配置:
- 允许你的前端源(
http://localhost:3002)访问,生产环境替换为正式域名 - 响应中必须包含
Access-Control-Allow-Origin头,值设为你的前端域名,或用*(生产环境不推荐,存在安全风险) - 对于POST这类非简单请求,后端需要处理OPTIONS预检请求,返回允许的请求方法、请求头等信息
3. 前端代码优化点
你的代码整体逻辑没问题,但有几处可以优化:
- 统一异步写法:避免
async/await和.then混用,改用纯async/await让代码更清晰:const getJwt = async (data) => { try { console.log(data); const response = await axios.post(`https://login.xxx.com/login`, { username: data.email, password: data.password, }); console.log(response.data.access); setCookie('accesstoken', response.data.access, { path: '/', httpOnly: true }); setCookie('refreshtoken', response.data.refresh, { path: '/', httpOnly: true }); dispatch(isLoggedInOn()); history.push('/'); } catch (err) { console.log("miss"); alert("Email or Password is wrong!"); } }; - 添加邮箱校验:当前邮箱输入框无校验规则,建议补充必填和格式校验:
<input placeholder='Email Address' className='form-control' {...register('email', { required: "Email is required", pattern: { value: /^\S+@\S+$/i, message: "Invalid email address" } })} /> - 修复Cookie参数格式:
react-cookie的setCookie配置需合并到同一个对象中,之前的写法会导致httpOnly不生效:setCookie('accesstoken', response.data.access, { path: '/', httpOnly: true }); - 优化错误提示:可利用
react-hook-form的errors对象展示字段级错误,替代全局alert。
内容的提问来源于stack exchange,提问作者user15346124
相关产品推荐
相关产品推荐

