reactjsflaskcorsfetch-apiflask-cors

CORS issue from React frontend calling Flask server


I'm building an app in React and I had some Python code I wanted to run, so I decided to turn the Python code into a small Flask server so I could access its results via an HTTP request. The Javascript file below makes the request to Flask server.

// someFile.js

export const getAnswer = async (param) => {
  let message = {
    tag: "1",
    content: "If you see this message, fetch is not working."
  };

  fetch(`http://127.0.0.1:5000/?message=${param}`)
    .then(response => response.text())
    .then(data => {
      message = {
        tag: "1",
        content: data
      }
    }
  )

  return message;
};

The file below is my Flask app.

# flaskFile.py

from flask import Flask, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route('/')
def handle_request():
    m = request.args.get('message', default = "Default")
    print(m)


    # logic...


    # response.headers.add("Access-Control-Allow-Origin", "*")
    return response

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

Whenever I send a test input through my front end e.g. "Is the flask server getting this message?" I see in my Flask server terminal that the Flask server is indeed receiving the message and printing it out (there is a print statement in handle_request()). However, the response that I'm getting from getAnswer is still "If you see this message, fetch is not working."

Is the flask server getting this message?
127.0.0.1 - - [10/Aug/2024 01:31:38] "GET /?message=Is%20the%20flask%20server%20getting%20this%20message? HTTP/1.1" 200 -

Therefore, my Flask server is getting the request from my front end, but my front end is seemingly not getting a response back. When I test my Flask server locally, everything runs perfectly. Some research has led me to believe it's a CORS issue.

I have already tried using flask_cors to solve my issue, as is shown in the code. I have also tried manually adding the "Access-Control-Allow-Origin: *" header to my response (in the line that has been commented out). In both this cases, I checked in terminal and found the responses were indeed getting tagged with the header (note I checked this in a separate terminal i.e. this fetch is not getting called from someFile.js). However, it is still not working.

> fetch(`http://127.0.0.1:5000/?message=${query}`).then(response => response.headers).then(data => console.log(data))
> Headers {
   server: 'Werkzeug/3.0.3 Python/3.8.5',
   date: 'Sat, 10 Aug 2024 08:21:01 GMT',
   'content-type': 'text/html; charset=utf-8',
   'content-length': '275',
   'access-control-allow-origin': '*',
   connection: 'close'
}

Any solutions or suggestions? Thanks for any help.


Solution

  • It looks like you are returning your message before the modification is made. You are declaring your function async but not using its functionality, try something like this using the async...await pattern :

    export const getAnswer = async (param) => {
      let message = {
        tag: "1",
        content: "If you see this message, fetch is not working."
      };
    
      const response = await fetch(`http://127.0.0.1:5000/?message=${param}`);
      const data = await response.text();
    
      if(data) {
        message = {
          tag: "1",
          content: data
        }
      }
    
      return message;
    };
    

    You could try adding a console.log in the last then, you would notice that it appears after the return of your function. async...await allows you to simply wait for the fetch response before to continue. Without it, you would need to do your modifications and find a way to get your modified message inside the then.