仅Apple Silicon Mac设备上Flask应用出现CORS违规问题求助
跨域请求在Apple Silicon Mac上的CORS问题及解决方案
问题复现代码
Flask后端API
from flask import Flask, jsonify, request from flask_cors import CORS app = Flask(__name__) CORS(app) # 全局启用CORS @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() processed_data = process_data(data) return jsonify({'processed_data': processed_data}) def process_data(data): 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()
前端测试页面
<!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>
错误现象
在M3/M2 Mac设备上访问localhost:8080测试时,浏览器控制台抛出以下错误:
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)
该问题仅出现在Apple Silicon系列Mac,Intel Mac和Windows设备运行正常,Chrome、Safari浏览器均会触发报错。
原因分析
flask-cors版本兼容性问题:旧版本的flask-cors库在ARM架构Mac上存在适配缺陷,无法正确注入Access-Control-Allow-Origin响应头。- Flask开发服务器网络监听差异:Apple Silicon架构下,Flask默认开发服务器的请求源检测逻辑存在细微偏差,导致CORS中间件无法正常识别跨域请求。
解决办法
1. 升级flask-cors到最新版本
执行命令更新依赖:
pip install --upgrade flask-cors
最新版本已修复ARM架构下的兼容性问题,能正确处理跨域响应头。
2. 显式指定允许的请求源
替换全局CORS配置,精准指定允许的前端域名:
# 替换原有的CORS(app) CORS(app, origins=["http://localhost:8080"])
这种方式可避免中间件自动检测失效的问题。
3. 手动添加CORS响应头
绕过flask-cors库,直接在路由函数中添加响应头:
@app.route('/api/hello', methods=['GET']) def hello(): name = request.args.get('name', 'World') message = f'Hello, {name}!' response = jsonify({'message': message}) response.headers.add('Access-Control-Allow-Origin', '*') return response
此方法最直接,确保响应头不受架构或库版本影响。
4. 启用Werkzeug代理修复
Flask依赖Werkzeug,启用代理修复可修正请求源检测异常:
from werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app)
内容的提问来源于stack exchange,提问作者Duncan Britt
相关产品推荐
相关产品推荐

