4 minute read

In this blog post I will go over how to set up your React and Flask project while avoiding the dreaded Cross-Origin Resource Sharing (CORS) error.

This is what the final demo looks like.

You can find the code on Github here.

Flask server

Setting up the Flask server is easy. Make a new python file server.py and add the following content.

from flask import Flask
from flask import jsonify
import time
app = Flask(__name__)

@app.route('/time')
def get_current_time():
    return jsonify({'time': time.time()})

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

What we basically do here is that we set up a Flask webserver with a single route called /time which returns a json object of the current time as a UNIX timestamp. If you start the server you should be greeted with the following output.

$ python3 server.py
 * Serving Flask app "server" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 212-654-497

Sending a simple GET request with Postman should return a json object with a single item called time which is a UNIX timestamp of the current time. We will try to send this to our React frontend.

{
  "time": 1594819306.902315
}

React frontend

Getting started with the React frontend is also easy because we have create-react-app. Assuming that we are already in the folder that you want to work from and have created the server.py file, we will now create a new react project in this folder.

npx create-react-app .

Now we just have to connect the React frontend with the Flask backend. We can do this by changing the contents of src/App.js into this.

import React, { useState, useEffect } from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
    const [currentTime, setCurrentTime] = useState(0);

    useEffect(() => {
        fetch('/time')
            .then((res) => res.json())
            .then((data) => {
                setCurrentTime(data.time);
            });
    }, []);

    return (
        <div className='App'>
            <header className='App-header'>
                <img src={logo} className='App-logo' alt='logo' />
                <p>The current time is {currentTime}.</p>
            </header>
        </div>
    );
}

export default App;

What does every line here do?

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

This imports useState and useEffect which we need to manage states and effects (which is a lifecycle method). useEffect allows us to “do something” after everything has rendered. We will use this to plug in the results from our api call to the Flask backend after everything has rendered.

const [currentTime, setCurrentTime] = useState(0);

Here we use the useState(0) function to first set the initial state to zero. We return the current state (currentTime) and a function to change the state (setCurrentTime). This is how useState() works.

useEffect(() => {
    fetch('/time')
        .then((res) => res.json())
        .then((data) => {
            setCurrentTime(data.time);
        });
}, []);

Here we call the method useEffect() which does something after all the components are rendered. We use fetch() to make a GET request to our endpoint /time which defaults to localhost:3000 which is where our React app is hosted. After receiving the endpoint we convert it into a json and then set the new state using the function setCurrentTime() to the timestamp we got from the api call.

return (
    <div className='App'>
        <header className='App-header'>
            <img src={logo} className='App-logo' alt='logo' />
            <p>The current time is {currentTime}.</p>
        </header>
    </div>
);

Then our render() function which renders the JSX simply has another dynamic field {currentTime} which displays the current time.

Avoiding CORS issues

Finally, add this proxy setting to your package.json.

{
  "proxy": "http://localhost:5000"
}

This is a crucial last step because if you to run your Flask server as a normal server and try to make an api call to it you will be blocked because of CORS.

Access to fetch at ‘http://127.0.0.1:5000/time’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

This is basically what is happening:

  • React runs on port 3000
  • Flask runs on port 5000
  • Usually for frontend and backend these are the same (so they “trust” each other)
  • If they are not the same they do not “trust” each other and you have cross-origin issues (CORS)
  • We configure React such that it forwards all requests it receives on 3000 to 5000
  • This is how we avoid the CORS issues

You should be ready to run the React frontend now.

npm start

Conclusion

You’re done! If you followed all the steps correctly your running React app should look like this.

That’s it! In this blog post I provide you with a very small demo repository that connects a React frontend with a Flask backend while avoiding CORS issues.

Subscribe

Comments