框架 | 推荐方案 | 特点 |
---|---|---|
Flask | flask-cors 扩展 |
简单易用,支持细粒度控制 |
Django | django-cors-headers 中间件 |
配置化,适合 Django 生态 |
原生 WSGI | 手动设置响应头 | 灵活但需要自行处理逻辑 |
pip install flask-cors
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # 允许所有域名访问所有路由
@app.route('/api/data')
def get_data():
return jsonify({"message": "CORS enabled for all origins"})
if __name__ == '__main__':
app.run(port=5000)
from flask import Flask, jsonify, make_response
from flask_cors import CORS
app = Flask(__name__)
CORS(
app,
origins=["https://your-frontend.com", "http://localhost:3000"], # 允许的域名
supports_credentials=True, # 允许携带 Cookie
methods=["GET", "POST", "PUT", "DELETE"], # 允许的方法
allow_headers=["Content-Type", "Authorization"] # 允许的请求头
)
@app.route('/api/login')
def login():
response = make_response(jsonify({"status": "Logged in"}))
response.set_cookie(
'user_token',
'token_value',
secure=True, # 仅 HTTPS
httponly=True,
samesite='None' # 允许跨站 Cookie
)
return response
if __name__ == '__main__':
app.run(ssl_context='adhoc') # 测试用自签名 HTTPS
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
cors = CORS() # 创建 CORS 实例
def dynamic_origin_check(origin):
# 自定义逻辑:检查域名是否在白名单
allowed_origins = ["https://trusted.com", "http://localhost:3000"]
return origin in allowed_origins
@app.route('/api/data')
def get_data():
# 手动设置响应头(示例)
origin = request.headers.get('Origin')
if dynamic_origin_check(origin):
response = jsonify({"data": "Dynamic CORS allowed"})
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Credentials'] = 'true'
return response
else:
return jsonify({"error": "Origin not allowed"}), 403
if __name__ == '__main__':
cors.init_app(app) # 初始化 CORS
app.run(port=5000)
pip install django-cors-headers
settings.py
# settings.py
INSTALLED_APPS = [
...
'corsheaders', # 添加应用
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 尽量靠前
...
]
# CORS 配置
CORS_ALLOWED_ORIGINS = [
"https://your-frontend.com",
"http://localhost:3000",
]
CORS_ALLOW_CREDENTIALS = True # 允许 Cookie
CORS_ALLOW_METHODS = [
'GET',
'POST',
'PUT',
'DELETE',
'OPTIONS',
]
CORS_ALLOW_HEADERS = [
'content-type',
'authorization',
]
# views.py
from django.http import JsonResponse
def api_data(request):
response = JsonResponse({"data": "Django CORS enabled"})
response.set_cookie(
'session_id',
'abc123',
secure=True,
httponly=True,
samesite='None',
max_age=3600
)
return response
from bottle import Bottle, response, request
app = Bottle()
# 手动设置 CORS 头
def enable_cors():
origin = request.headers.get('Origin', '*')
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Authorization'
response.headers['Access-Control-Allow-Credentials'] = 'true'
@app.hook('after_request')
def apply_cors():
enable_cors()
@app.route('/api/data')
def get_data():
return {"message": "Manual CORS handling"}
if __name__ == '__main__':
app.run(port=8080)
samesite='None'
+ secure=True
(仅 HTTPS 生效)credentials: 'include'
(浏览器端)
fetch(url, { credentials: 'include' })
@app.route('/api/data', method=['OPTIONS'])
def handle_options():
enable_cors()
return ''
origins="*"
CorsMiddleware
需在靠前位置)supports_credentials=True
(Flask)或 CORS_ALLOW_CREDENTIALS=True
(Django)SameSite
和 Secure
属性是否正确credentials: 'include'
CORS_ALLOW_HEADERS
(Django)或 allow_headers
(Flask)中添加头名称Access-Control-Allow-Headers
中声明使用 curl
或 Postman 验证响应头:
curl -I -X OPTIONS http://localhost:5000/api/data
# 检查返回的 Access-Control-* 头