如何解决Netlify与Heroku部署Flutter-Django应用的CORS跨域问题
核心问题定位
错误提示明确指出Heroku上的Django后端未返回Access-Control-Allow-Origin响应头,因此问题根源在Django的CORS配置,Netlify的前端CORS设置不影响后端的跨域控制。
具体解决步骤
修正Django中间件顺序
确保corsheaders.middleware.CorsMiddleware是MIDDLEWARE列表中的第一个中间件,必须放在django.middleware.common.CommonMiddleware之前,否则后续中间件可能在CORS头添加前就发送了响应。示例:MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 其他中间件... ]更新CORS白名单配置(适配Django版本)
- 若使用Django 3.2及以上版本,
CORS_ORIGIN_WHITELIST已废弃,需改用CORS_ALLOWED_ORIGINS。 - 白名单中的URL必须精确匹配:包含完整协议(
https://),不能带末尾斜杠。例如:# 正确写法 CORS_ALLOWED_ORIGINS = [ "https://your-netlify-site.netlify.app", "https://your-heroku-app.herokuapp.com" ] - 替换占位符
[netlify url]为实际的Netlify域名,避免格式错误。
- 若使用Django 3.2及以上版本,
验证Heroku环境变量加载
- 检查
settings.py中是否正确读取Heroku配置变量,例如:import os ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "").split(",") CORS_ALLOWED_ORIGINS = os.environ.get("CORS_ALLOWED_ORIGINS", "").split(",") - 登录Heroku后台,确认
ALLOWED_HOSTS和CORS_ALLOWED_ORIGINS配置变量的内容正确,无拼写错误或多余空格。
- 检查
测试OPTIONS预检请求
浏览器发送POST/PUT等请求前会先发送OPTIONS预检请求,用curl验证后端响应:curl -X OPTIONS -H "Origin: https://你的Netlify域名" https://你的Heroku域名/api/login检查响应头中是否包含
Access-Control-Allow-Origin,若没有,说明CORS中间件未生效。排查其他中间件干扰
临时禁用自定义中间件或安全类中间件(如django.middleware.security.SecurityMiddleware)后测试,确认是否有中间件覆盖或删除了CORS响应头。临时开启全局CORS测试
暂时设置CORS_ORIGIN_ALLOW_ALL = True,部署后验证错误是否消失。若解决,说明白名单配置有误;若未解决,说明CORS中间件未正确安装或加载。检查Flutter Web请求配置
确认Flutter Web中请求的后端URL是Heroku正式域名,而非本地测试地址;同时确保请求未手动添加冲突的Origin头。
内容的提问来源于stack exchange,提问作者Zuckerbrenner

