-1

My ReactJS app cannot successfully send form data to Python flask backend, even with a CORS statement in the backend.

This is the error message:

Access to XMLHttpRequest at 'http://localhost:5000/' from origin 'http://localhost:3000' 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.

I'm not sure what I am missing. Could anybody point out where to fix? Thanks!

EDIT I simplified the code snippets below to identify the cause easier.

This is an excerpt of my react frontend.

import React, { useState } from 'react';
import axios from 'axios';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  const [destination, setDestination] = useState('Amsterdam');

  const handleSubmit = async (e) => {
    e.preventDefault();
    const data = {
      destination: destination,
    };
    console.log(data);
    const response = await axios.post('http://localhost:5000/', data);
  };

  return (
    <div >
      <BrowserRouter>
        <Routes>
          <Route path="/" element={
            <div>
              <form onSubmit={handleSubmit} style={{ textAlign: "center" }}>
                <div>
                  <label>
                    Destination:
                    <input
                      type="text"
                      value={destination}
                      onChange={(e) => setDestination(e.target.value)}
                    />
                  </label>
                </div>
                <button type="submit">Submit</button>
              </form>
            </div>
          }>
          </Route>
        </Routes>
      </BrowserRouter>
    </div >
  );
}

export default App;

And this is an excerpt of my app.py

from flask import Flask, render_template, request, redirect, session, url_for, jsonify
from flask_session import Session
from flask_cors import CORS, cross_origin

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})

print("app.py running")

Session(app)

@app.route("/", methods=["GET", "POST"])
@cross_origin()
def index():
    print("function called")
    if request.method == "POST":
        print(request.form['destination'])
        return "success!"
    # Add the following lines to set the 'Access-Control-Allow-Origin' header
    response = jsonify({'message': 'Hello, World!'})
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response

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

EDIT I modified my app.py where I made a separate route. However the same error still persists.

@app.route("/", methods=["GET", "POST"])
@cross_origin()
def index():
    print("function called")
    if request.method == "POST":
        print(request.form['destination'])
        return "success!"

@app.route("/", methods=["OPTIONS"])
@cross_origin()
def handle_options_request():
    # Set CORS headers
    headers = {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST',
        'Access-Control-Allow-Headers': 'Content-Type'
    }
    return ('', 204, headers)
Makoto Miyazaki
  • 1,743
  • 2
  • 23
  • 39
  • Instead of manually implementing CORS (which is error-prone), you should rely on a proven CORS middleware. – jub0bs Mar 02 '23 at 08:44
  • Take a look at the Network tab on Chrome Dev Tools (F12) as the form is submitted. You should see the OPTIONS request send and possibly the POST request. Check the response codes and headers of those requests. You need to verify the `Access-Control-Allow-Origin` header is present in the responses. – MrCode Mar 02 '23 at 11:04

1 Answers1

-1

Theory: https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

Some answers I found here on this site:

so try adding "OPTION" to your methods:

- @app.route("/signup", methods=["GET", "POST"])
+ @app.route("/signup", methods=["GET", "POST", "OPTION"])
  def signup():
Simon Laux
  • 382
  • 1
  • 14
  • Thanks for the resources. I fixed as you instructed but the same error still persists... – Makoto Miyazaki Mar 01 '23 at 22:09
  • maybe you need to create a separate route for it then, like accept all option requests to all routes and just return the CORS headers on them, like the documentation suggested – Simon Laux Mar 01 '23 at 22:28
  • Thank you. I created a separate route as you suggested. However it's still the same. I simplified the code snippets in hope of causing the spots more easily. I really hope to solve this... – Makoto Miyazaki Mar 01 '23 at 22:54
  • you could also try this package, it was linked in one of the answers of the thread I linked: https://stackoverflow.com/a/26395623/7655232 – Simon Laux Mar 01 '23 at 22:59