本文目录导读:

- 目录导读
- 什么是跨域问题?为什么会出现?
- 跨域的常见解决方案对比
- Python Flask 实现跨域:完整案例
- Python Django 实现跨域:使用 django-cors-headers
- FastAPI 跨域设置:极简异步方案
- 常见问题问答(FAQ)
- 总结与最佳实践建议
Python案例详解:如何优雅实现接口跨域(附完整代码)
目录导读
- 什么是跨域问题?为什么会出现?
- 跨域的常见解决方案对比与选择
- Python Flask 实现跨域:一步步实战案例
- Python Django 实现跨域:CORS模块配置
- FastAPI 跨域设置:现代异步方案
- 常见问题问答(FAQ)
- 总结与最佳实践建议
什么是跨域问题?为什么会出现?
跨域(Cross-Origin) 指的是浏览器出于安全考虑,限制一个网页中加载的脚本,去访问另一个不同域名(或端口、协议)下的资源,前端 http://localhost:3000 向后端 http://localhost:5000 发请求,浏览器就会报错:
Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy.
这个机制叫同源策略,目的是防止恶意网站窃取用户数据,但实际开发中,前后端分离、微服务架构、第三方API调用都会触发跨域,因此我们需要服务端主动放行。
跨域的常见解决方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| CORS(跨域资源共享) | 标准、灵活、无需代理 | 需要后端设置,复杂请求需预检 |
| JSONP | 兼容旧浏览器 | 仅支持GET,不安全,已过时 |
| 反向代理(Nginx/Node) | 不改后端代码,生产常用 | 增加部署复杂度 |
| WebSocket | 天然支持跨域 | 需要协议支持,业务场景有限 |
推荐使用 CORS,这是目前前后端分离项目的标准做法,下面结合Python主流框架演示。
Python Flask 实现跨域:完整案例
场景:前端Vue应用访问Flask API,端口不同。
手动设置响应头
from flask import Flask, jsonify, make_response
app = Flask(__name__)
@app.route('/api/data')
def get_data():
response = make_response(jsonify({'message': 'Hello CORS!'}))
response.headers['Access-Control-Allow-Origin'] = '*' # 允许所有域名
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
return response
if __name__ == '__main__':
app.run(port=5000)
使用 flask-cors 扩展(推荐)
pip install flask-cors
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources={r"/api/*": {"origins": "*"}}) # 对/api路径下所有接口开放
@app.route('/api/data')
def get_data():
return jsonify({'message': 'CORS enabled via extension'})
if __name__ == '__main__':
app.run(port=5000)
测试方法:用浏览器或Postman直接访问 http://localhost:5000/api/data,观察响应头中是否包含 Access-Control-Allow-Origin: *。
Python Django 实现跨域:使用 django-cors-headers
Django默认不允许跨域,需安装第三方库:
pip install django-cors-headers
settings.py 配置:
INSTALLED_APPS = [
...
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 尽量放在前面
...
]
# 允许所有域名(开发环境)
CORS_ALLOW_ALL_ORIGINS = True
# 或指定白名单(生产环境)
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"https://myapp.example.com",
]
# 允许携带凭证(如需Cookies)
CORS_ALLOW_CREDENTIALS = True
视图代码无需改动,中间件会自动处理跨域请求。
FastAPI 跨域设置:极简异步方案
FastAPI 天生支持 CORS,通过 CORSMiddleware 配置:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许域名列表
allow_credentials=True,
allow_methods=["*"], # 允许所有HTTP方法
allow_headers=["*"], # 允许所有请求头
)
@app.get("/api/data")
async def get_data():
return {"message": "FastAPI CORS ready"}
注意:设置 allow_origins=["*"] 时,allow_credentials 必须为 False,否则会触发安全错误,如果需要携带凭证,要显式列出域名。
常见问题问答(FAQ)
Q1:设置了CORS还是报跨域错误,为什么?
A1:检查是否遗漏了预检请求(OPTIONS) 的处理,复杂请求(如带自定义头、PUT/POST等)会先发OPTIONS探询服务端是否允许,确保后端正确响应200。
*Q2:`Access-Control-Allow-Origin: 有安全隐患吗?** A2:生产环境中不建议使用星号,应限定具体域名,若使用星号,则无法使用withCredentials`(Cookie/Session)。
Q3:如何调试跨域问题?
A3:打开浏览器开发者工具 → Network → 查看预检请求和实际请求的响应头,常见工具:curl -I 或者 Postman模拟OPTIONS请求。
Q4:Nginx反向代理能解决跨域吗?
A4:可以,将前后端部署在同一域名下(如 /api 转发到后端, 指向前端),即可避免跨域,配置示例:
location /api/ {
proxy_pass http://127.0.0.1:5000/;
}
这属于生产环境的经典方案,但本地开发仍推荐CORS。
总结与最佳实践建议
- 开发阶段:使用对应框架的CORS扩展,允许 即可,方便调试。
- 生产阶段:限制
AllowedOrigins为具体域名,配合allow_credentials=False提高安全性。 - 复杂场景:若需携带Cookie或Token认证,必须设置
AllowedOrigins为具体域名,且不能使用通配符。 - 如果后端是微服务架构,建议统一在API网关(如Kong、Traefik)层处理CORS,避免每个服务重复配置。
跨域本质是浏览器安全策略,服务端只需正确返回CORS头部即可解决,掌握Python三大框架的实现,足以应对绝大多数前后端分离项目。