I am developing a simple application using Flask for the backend and React for the frontend. When I try to start my React application using npm start, I encounter a CORS error. However, when I use HOST=127.0.0.1 npm start, the application runs successfully without any CORS error.
Here is the code snippet for the Flask application:
#!/usr/bin/env python3
from flask import Flask
from flask_cors import CORS
from os import environ
try:
origins = environ["ORIGINS"]
except KeyError:
kwargs = {}
else:
if "," in origins:
origins = origins.split(",")
kwargs = dict(resources={r"/*": dict(origins=origins)})
print(kwargs)
app = Flask(__name__)
CORS(app, **kwargs)
@app.route("/")
def index():
return "reached\n"
if __name__ == "__main__":
app.run(port=5000)
Here is the code snippet for the React application:
import React, { useEffect, useState } from 'react';
const localhost = window.location.hostname
function App() {
const [response, setResponse] = useState('');
useEffect(() => {
document.title = localhost
fetch(`http://${localhost}:5000/`)
.then((response) => {
if (!response.ok) {
throw Error('Network response was not ok');
}
return response.text();
})
.then((data) => setResponse(data))
.catch((error) => console.log(error));
}, []);
return (
<div>
<h2>"reached" expected:</h2>
<p>{response}</p>
</div>
);
}
export default App;
I am using the hostname dynamically from window.location.hostname for the fetch URL. Does anyone know why specifying the host as 127.0.0.1 resolves the CORS error, while just using npm start does not?
With the help of ChatGPT, I created the following program:
#!/usr/bin/env python3
# clnt.py
import requests
from os import environ
LOCALHOST = environ.get("LOCALHOST", "127.0.0.1")
headers = {
"Origin": f"http://{LOCALHOST}:3000",
}
response = requests.get(f"http://{LOCALHOST}:5000", headers=headers)
print("Status Code:", response.status_code)
print("Response Content:", response.content)
print("Response Headers:", response.headers)
I simplified the Flask program as follows:
#!/usr/bin/env python3
# serv.py
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/")
def index():
return "reached\n"
if __name__ == "__main__":
app.run(port=5000)
Then, I tried the following:
#!/bin/bash
./serv.py &
serv=$!
sleep 1
./clnt.py
LOCALHOST=localhost ./clnt.py
kill $serv
As a result, the above script output:
127.0.0.1 - - [26/Sep/2023 18:03:21] "GET / HTTP/1.1" 200 -
Status Code: 200
Response Content: b'reached\n'
Response Headers: {'Server': 'Werkzeug/2.3.7 Python/3.9.6', 'Date': 'Tue, 26 Sep 2023 09:03:21 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '8', 'Access-Control-Allow-Origin': 'http://127.0.0.1:3000', 'Vary': 'Origin', 'Connection': 'close'}
Status Code: 403
Response Content: b''
Response Headers: {'Content-Length': '0', 'Server': 'AirTunes/695.5.1'}
It seems that the AirTunes server was using port 5000.
I modified clnt.py and serv.py so that the port could be variable:
PORT=5001 ./serv.py &
serv=$!
sleep 1
PORT=5001 ./clnt.py
PORT=5001 LOCALHOST=localhost ./clnt.py
kill $serv
As a result, I obtained the expected output:
127.0.0.1 - - [26/Sep/2023 18:03:23] "GET / HTTP/1.1" 200 -
Status Code: 200
Response Content: b'reached\n'
Response Headers: {'Server': 'Werkzeug/2.3.7 Python/3.9.6', 'Date': 'Tue, 26 Sep 2023 09:03:23 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '8', 'Access-Control-Allow-Origin': 'http://127.0.0.1:3000', 'Vary': 'Origin', 'Connection': 'close'}
127.0.0.1 - - [26/Sep/2023 18:03:23] "GET / HTTP/1.1" 200 -
Status Code: 200
Response Content: b'reached\n'
Response Headers: {'Server': 'Werkzeug/2.3.7 Python/3.9.6', 'Date': 'Tue, 26 Sep 2023 09:03:23 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '8', 'Access-Control-Allow-Origin': 'http://localhost:3000', 'Vary': 'Origin', 'Connection': 'close'}
The front-end and back-end programs presented in the original question started working as expected after changing the port from 5000 to 5001 (provisionally).