Parzival
Parzival

Reputation: 329

Flask CORS Issue: "No 'Access-Control-Allow-Origin' header is present on the requested resource"

I'm working on a web application where the frontend is built with React (running on http://localhost:3000) and the backend is built using Flask (running on http://localhost:5000). I'm trying to enable CORS on the Flask backend to allow cross-origin requests, but I keep encountering the following error when making a request from the frontend:

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

I've installed and configured Flask-CORS on the backend, and I’ve tried several configurations, but the issue persists. Here's a breakdown of my setup.

init.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_cors import CORS

db = SQLAlchemy()
bcrypt = Bcrypt()

def create_app():
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    app.secret_key = 'supersecretkey'

    db.init_app(app)
    bcrypt.init_app(app)

    # Enable CORS for all routes and allow requests from localhost:3000
    CORS(app, resources={r"/*": {"origins": "http://localhost:3000"}}, supports_credentials=True)

    # Ensure CORS headers are present in all responses
    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000')
        response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
        response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
        return response

    from .routes import main
    app.register_blueprint(main)

    return app

routes.py

from flask import Blueprint, request, jsonify
from .models import User
from . import db

main = Blueprint('main', __name__)

@main.route('/signup', methods=['POST'])
def signup():
    data = request.get_json()
    username = data['username']
    email = data['email']
    password = data['password']

    user = User.query.filter_by(email=email).first()

    if user:
        return jsonify({'message': 'User already exists'}), 400

    new_user = User(username=username, email=email)
    new_user.set_password(password)
    db.session.add(new_user)
    db.session.commit()

    return jsonify({'message': 'User created successfully'}), 201


@main.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    email = data['email']
    password = data['password']

    user = User.query.filter_by(email=email).first()

    if user and user.check_password(password):
        return jsonify({'message': 'Login successful'}), 200

    return jsonify({'message': 'Invalid credentials'}), 401


# make default home page
@main.route('/')
def index():
    return jsonify({'message': 'Backend Running'})


@main.route('/test', methods=['GET'])
def test_route():
    return {"message": "CORS is working!"}

React frontend (signup.js)

import React, { useEffect } from 'react';
import axios from 'axios';

const Signup = () => {

  // Test the backend /test route
  useEffect(() => {
    axios.get('http://localhost:5000/test')
      .then(response => console.log(response.data))
      .catch(error => console.error(error));
  }, []);

  return (
    <div>
      <h2>Signup Page</h2>
    </div>
  );
};

export default Signup;

What I've Tried: Installed Flask-CORS:

Verified that Flask-CORS is installed and configured as shown above. The CORS setup is placed before the routes are registered in the create_app function. Checked the Browser’s Network Tab:

The OPTIONS request shows that no Access-Control-Allow-Origin header is present. This causes the POST/GET requests to fail due to CORS. Cleared Cache and Tried in Incognito Mode:

I’ve also tried disabling browser caching and tested the app in incognito mode, but the issue persists.

Expected Behavior: The Flask backend should return the necessary CORS headers, including Access-Control-Allow-Origin: http://localhost:3000, allowing the React frontend to make requests without CORS issues.

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

Question: What am I missing in my Flask configuration to properly enable CORS? Why is the Access-Control-Allow-Origin header not being added to the response, despite using Flask-CORS? Any help or pointers would be greatly appreciated!

Upvotes: -1

Views: 181

Answers (1)

rampollaluis
rampollaluis

Reputation: 1

Why was this section added?

# Ensure CORS headers are present in all responses
@app.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
    response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
    return response

I've never personally needed it when using flask-cors.

Their pypi page doesn't seem to suggest you need it either.

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

Also, make sure your create_app() is actually called like

app = create_app()

if __name__ == '__main__':
    app.run(debug=True)

and that it is not still

app = Flask(__name__)

Finally, you can try making sure if you remove the CORS or allow all origins with CORS(app, resources={r"/api/*": {"origins": "*"}}) that a curl to your endpoint works as you expect.

curl 127.0.0.1:5000/test

Upvotes: -1

Related Questions