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

React与Flask集成遇CORS错误:XMLHttpRequest请求被拦截

问题:ReactJS前端与Flask后端集成时的CORS错误

Access to XMLHttpRequest at 'http://localhost:5000/api/auth/login' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

后端Flask代码(app.py)

from flask import Flask, request, session, redirect, url_for, render_template, flash, jsonify
import psycopg2
import psycopg2.extras
from werkzeug.security import generate_password_hash, check_password_hash
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True) # 尝试为所有路由启用CORS
app = Flask(__name__)
app.secret_key = 'secretkey'
DB_HOST = "localhost"
DB_NAME = "Dbname"
DB_USER = "user"
DB_PASS = "password"
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST)

@app.route('/')
def home():
    if 'loggedin' in session:
        if request.headers.get('Content-Type') == 'application/json':
            return jsonify({'username': session['username']})
        return render_template('home.html', username=session['username'])
    return jsonify({'message': '用户未登录'})

@app.route('/api/auth/login', methods=['POST','OPTIONS'])
def api_login():
    cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    if request.method == 'OPTIONS':
        response = jsonify()
        response.headers['Access-Control-Allow-Origin'] = 'http://localhost:3000'
        response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
        response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
        return response, 200

    if request.headers.get('Content-Type') == 'application/json':
        data = request.get_json()
        username = data.get('username')
        password = data.get('password')

        cursor.execute('SELECT * FROM users WHERE username = %s', (username,))
        account = cursor.fetchone()

        if account and check_password_hash(account['password'], password):
            session['loggedin'] = True
            session['id'] = account['id']
            session['username'] = account['username']
            return jsonify({'message': '登录成功', 'username': account['username']})
        else:
            return jsonify({'message': '用户名/密码错误'})

    return jsonify({'message': '无效请求'})


@app.route('/login', methods=['POST'])
def login():
    cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    if request.headers.get('Content-Type') == 'application/json':
        data = request.get_json()
        username = data.get('username')
        password = data.get('password')

        cursor.execute('SELECT * FROM users WHERE username = %s', (username,))
        account = cursor.fetchone()

        if account and check_password_hash(account['password'], password):
            session['loggedin'] = True
            session['id'] = account['id']
            session['username'] = account['username']
            return jsonify({'message': '登录成功', 'username': account['username']})
        else:
            return jsonify({'message': '用户名/密码错误'})

    return jsonify({'message': '无效请求'})

@app.route('/register', methods=['POST'])
def register():
    cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    if request.headers.get('Content-Type') == 'application/json':
        data = request.get_json()
        fullname = data.get('fullname')
        username = data.get('username')
        password = data.get('password')
        email = data.get('email')
        CnrNumber = data.get('CnrNumber')
        phonenumber = data.get('phonenumber')

        _hashed_password = generate_password_hash(password)

        cursor.execute('SELECT * FROM users WHERE username = %s', (username,))
        account = cursor.fetchone()

        if account:
            return jsonify({'message': '该账号已存在!'})

        cursor.execute('INSERT INTO users (fullname, username, password, email, CnrNumber, phonenumber) VALUES (%s, %s, %s, %s, %s, %s)',
                       (fullname, username, _hashed_password, email, CnrNumber, phonenumber))
        conn.commit()

        return jsonify({'message': '注册成功'})

    return jsonify({'message': '无效请求'})

@app.route('/logout')
def logout():
    if request.headers.get('Content-Type') == 'application/json':
        session.pop('loggedin', None)
        session.pop('id', None)
        session.pop('username', None)
        return jsonify({'message': '登出成功'})

    return redirect(url_for('login'))

@app.route('/profile')
def profile():
    cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    if request.headers.get('Content-Type') == 'application/json':
        if 'loggedin' in session:
            cursor.execute('SELECT * FROM users WHERE id = %s', [session['id']])
            account = cursor.fetchone()
            return jsonify({'message': '个人信息', 'account': dict(account)})
        return jsonify({'message': '用户未登录'})

    return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(port=5000)

前端React代码(Login.js)

// Login.js
import React, { useState } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
import './assets/css/Login.css';
import siginup from './assets/images/signup/Signuprobo.png';

const Login = () => {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const navigate = useNavigate();

  const handleFormSubmit = async (e) => {
    e.preventDefault();
    try {
      setLoading(true);
      const response = await axios.post('http://localhost:5000/api/auth/login', {
        username: username,
        password: password,
      },{ withCredentials: true });
      localStorage.setItem('user-info', JSON.stringify(response.data));
      navigate('/home');
    } catch (error) {
      setError('用户名或密码错误,请重试。');
    } finally {
      setLoading(false);
    }
  };

  const handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      handleFormSubmit(e);
    }
  };

  return (
    <>
        <header>
            <div className="login-container">
                <div className='flex-container' style={{ display: 'flex', alignItems:'flex-start' }}>
                    <div className='image-container'>
                        <h1 className=''>CASE <br /> MINISTER</h1>
                        <img src={siginup} alt="登录图片" />
                    </div>
                    <form onSubmit={handleFormSubmit}>
                    <div className='input-container'>
                        <h2 className='text-light'>注册</h2>
                        <p>立即注册,获取专属内容访问权限!</p>
                        <label htmlFor="">邮箱地址</label>
                        <input
                            type="text"
                            placeholder='name@gmail.com'
                            onChange={(e) => setUsername(e.target.value)}
                            className='form-control'
                            autoComplete="off"
                            required
                        />
                        <br />
                        <label htmlFor="">密码</label>
                        <input
                            type="password"
                            placeholder='password'
                            onChange={(e) => setPassword(e.target.value)}
                            onKeyDown={(e) => e.key === 'Enter' && handleFormSubmit(e)}
                            className='form-control'
                            autoComplete="new-password"
                            required 
                        />
                       
                        <p style={{marginTop:'3px'}}>忘记密码?<a href='' style={{textDecoration:'none'}}>重置密码</a></p>
                        <button className='signup' type='submit'>注册</button>
                        <p style={{marginTop:'1rem'}}>点击注册,即表示您同意我们的服务条款和隐私政策。</p>
                        <div className="or-container">
                            <span className="line"></span>
                            <span className="or-text">或</span>
                            <span className="line"></span>
                        </div>

                        
                        {/* <GoogleLogin 
                            onSuccess={credentialResponse => {
                                console.log(credentialResponse);
                            }}
                            onError={() => {
                                console.log('登录失败');
                            }}
                        />; */}
                    </div>
                    </form>
                </div>
            </div>

        </header>
    </>
);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:34:56