部署在Heroku上的Django与React联用时出现CORS错误
首先,咱们先抓准错误的核心:你看到的 Redirect is not allowed for a preflight request 是关键线索——这说明你的API请求触发了重定向(比如HTTP跳转到HTTPS,或者路径错误导致301/302),而浏览器的预检OPTIONS请求是不允许被重定向的,直接就拦截了请求。下面一步步来修复:
1. 修正API请求地址(最常见的原因)
Heroku部署的应用默认强制使用HTTPS,如果你的React代码里请求的API地址是HTTP协议,或者是不完整的域名(比如只写了myapi而不是https://your-heroku-app-name.herokuapp.com/api/login),Heroku会自动把请求重定向到HTTPS版本,这就触发了预检请求的重定向错误。
解决办法:确保React里的createSession函数使用的是完整的HTTPS API地址,比如:
// 替换成你的Heroku应用实际地址 const API_BASE_URL = 'https://your-heroku-app-name.herokuapp.com/api'; const createSession = async (email, password) => { return await api.post(`${API_BASE_URL}/login/`, { email, password }); };
2. 调整Django中间件的顺序
你的MIDDLEWARE配置里,corsheaders.middleware.CorsMiddleware的位置不对——它必须放在django.middleware.common.CommonMiddleware之前,才能在其他中间件(比如处理重定向的中间件)之前设置好CORS响应头。
修改后的MIDDLEWARE应该是这样:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'corsheaders.middleware.CorsMiddleware', # 移到这里,必须在CommonMiddleware之前 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', ]
3. 优化CORS配置(可选但更严谨)
虽然你设置了CORS_ORIGIN_ALLOW_ALL = True,但生产环境更推荐明确指定允许的源,同时确保预检请求能正常通过:
# 替换成你的React地址,本地和生产环境都可以添加 CORS_ORIGIN_WHITELIST = [ "http://localhost:3000", # "https://your-production-react-app.com" # 如果有生产环境地址,也加上 ] # 明确允许的HTTP方法,覆盖默认配置 CORS_ALLOW_METHODS = [ "DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT", ] # 允许的请求头,确保Authorization等头能正常传递 CORS_ALLOW_HEADERS = [ "accept", "accept-encoding", "authorization", "content-type", "origin", "user-agent", "x-requested-with", ]
4. 检查Heroku的Django生产配置
确保你的settings.py里生产环境的配置正确:
# 生产环境必须关闭DEBUG DEBUG = False # 强制HTTPS重定向(Heroku推荐) SECURE_SSL_REDIRECT = True # 正确配置ALLOWED_HOSTS,不要用*(生产环境不安全) ALLOWED_HOSTS = ['your-heroku-app-name.herokuapp.com']
最后验证步骤
- 把修改后的Django代码重新部署到Heroku
- 确保React里的API请求地址是完整的HTTPS路径
- 清除浏览器缓存(避免旧的重定向缓存影响),然后测试登录请求
这样应该就能解决预检请求被重定向的问题,进而解决CORS拦截的错误了。
内容的提问来源于stack exchange,提问作者Pefori

