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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:15:46