pythoncorsapple-silicon

CORS violation only on Apple Silicon Macs in Flask app


I have reproduced this error with the following python backend api using flask.

from flask import Flask, jsonify, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app)  # Enable CORS for all routes and origins

@app.route('/api/hello', methods=['GET'])
def hello():
    name = request.args.get('name', 'World')
    message = f'Hello, {name}!'
    return jsonify({'message': message})

@app.route('/api/data', methods=['POST'])
def receive_data():
    data = request.get_json()
    # Process the received data
    processed_data = process_data(data)
    return jsonify({'processed_data': processed_data})

def process_data(data):
    # Apply upper() to all string values in the dictionary
    processed_data = {}
    for key, value in data.items():
        if isinstance(value, str):
            processed_data[key] = value.upper()
        else:
            processed_data[key] = value
    return processed_data

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

And I have a front end as follows:

<!DOCTYPE html>
<html>
<head>
    <title>Flask API Test</title>
</head>
<body>
    <h1>Flask API Test</h1>

    <h2>GET Request</h2>
    <label for="name">Name:</label>
    <input type="text" id="name" placeholder="Enter a name">
    <button onclick="sendGetRequest()">Send GET Request</button>
    <p id="getResult"></p>

    <h2>POST Request</h2>
    <label for="data">Data:</label>
    <input type="text" id="data" placeholder="Enter some data">
    <button onclick="sendPostRequest()">Send POST Request</button>
    <p id="postResult"></p>

    <script>
     function sendGetRequest() {
         const name = document.getElementById('name').value;
         const url = `http://localhost:5000/api/hello?name=${encodeURIComponent(name)}`;

         fetch(url)
             .then(response => response.json())
             .then(data => {
                 document.getElementById('getResult').textContent = data.message;
             })
             .catch(error => {
                 console.error('Error:', error);
             });
     }

     function sendPostRequest() {
         const data = document.getElementById('data').value;
         const url = 'http://localhost:5000/api/data';

         fetch(url, {
             method: 'POST',
             headers: {
                 'Content-Type': 'application/json'
             },
             body: JSON.stringify({ data: data })
         })
             .then(response => response.json())
             .then(data => {
                 console.log(data.processed_data);
                 document.getElementById('postResult').textContent = data.processed_data.data;
             })
             .catch(error => {
                 console.error('Error:', error);
             });
     }
    </script>
</body>
</html>

When I go to localhost:8080 and try it out on an M3 mac, I get these errors:

localhost/:1 Access to fetch at 'http://localhost:5000/api/hello?name=George' from origin 'http://localhost:8080' 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.
(index):26 
        
        
       GET http://localhost:5000/api/hello?name=George net::ERR_FAILED 403 (Forbidden)
sendGetRequest @ (index):26
onclick @ (index):12
(index):32 Error: TypeError: Failed to fetch
    at sendGetRequest ((index):26:10)
    at HTMLButtonElement.onclick ((index):12:40)

However, when I run in on my 2015 macbook pro, it works flawlessly. A colleague with an M2 mac has the error, but another colleague running windows has no problem. I have tried it on chrome and safari on my computers.

Any ideas as to what's going on here or what can be done about it??

P.S. I put all the code here: https://github.com/Duncan-Britt/cors-test if you want to try it out for yourself.


Solution

  • My teammate figured it out. Apparently the new laptops are using port 5000 for AirPlay. By serving the backend to port 5555, there is no more problem.