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
相关产品推荐
相关产品推荐

