React/DRF仅部分接口出现No 'Access-Control-Allow-Origin' CORS错误求助
解决Django CORS部分接口异常及后续请求连锁失败问题
问题重现
遇到CORS错误:
Access to fetch at 'https://___backend.herokuapp.com/api/tickets/21/' from origin 'http://___frontend.herokuapp.com' 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.
当前Django django-cors-headers 配置:
CORS_ALLOW_ALL_ORIGINS = False CORS_ALLOW_CREDENTIALS = True CORS_ALLOWED_ORIGINS = ["https://____frontend.herokuapp.com"] CSRF_TRUSTED_ORIGINS = ["https://____frontend.herokuapp.com"] CORS_ALLOW_HEADERS = DEFAULT_HEADERS # 该列表包含Access-Control-Allow-Origin CORS_ALLOW_METHODS = [ "DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT", ]
已确认:
- CORS中间件已放在中间件列表顶部
- 已将
corsheaders添加到INSTALLED_APPS
异常现象:
- 前端使用统一请求配置,但仅2个GET接口触发上述CORS错误:
const requestOptions = { method: 'GET', headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json', 'Authorization': `Token ${localStorage.getItem('token')}` } }
- 一旦这两个接口触发错误,后续调用登出接口也会出现相同CORS错误;若未访问这两个接口,登出接口正常工作。
排查与解决思路
1. 核对域名协议匹配性
错误信息里前端Origin是http://___frontend.herokuapp.com,但配置里的CORS_ALLOWED_ORIGINS是https://____frontend.herokuapp.com,协议不匹配会直接导致CORS中间件拒绝添加响应头。
- 优先将前端访问协议切换为HTTPS(Heroku默认支持HTTPS)
- 若需兼容HTTP,在
CORS_ALLOWED_ORIGINS中补充http://___frontend.herokuapp.com
2. 检查异常接口的响应生成逻辑
- 查看这两个接口的视图是否在CORS中间件处理前就抛出了异常(比如权限校验失败、500错误):如果视图提前返回错误响应,CORS中间件来不及注入响应头
- 确认视图是否手动构造了Response对象:若未使用Django原生的HttpResponse类,可能导致CORS头无法被添加
- 排查视图装饰器:比如自定义权限装饰器、
@csrf_exempt是否干扰了中间件执行顺序
3. 分析请求细节与预请求处理
- 用浏览器Network面板查看异常接口的实际请求头:确认Origin是否与配置一致,Authorization Token是否有效
- 检查OPTIONS预请求:虽然配置允许OPTIONS方法,但如果视图未处理OPTIONS请求,会导致预请求失败,进而触发CORS错误
4. 排查会话/Token的连锁影响
- 异常接口触发后后续请求报错,大概率是该请求导致了服务器端会话或Token状态异常(比如Token过期、会话被销毁),使得后续请求返回错误响应时未携带CORS头
- 触发错误后,检查浏览器Cookie、LocalStorage中的Token是否还存在,状态是否正常
5. 临时调试定位问题
- 临时将
CORS_ALLOW_ALL_ORIGINS设为True,若接口恢复正常,说明是CORS_ALLOWED_ORIGINS的配置问题(比如域名拼写错误、协议遗漏) - 显式定义
CORS_ALLOW_HEADERS,避免依赖DEFAULT_HEADERS的默认值,比如:
CORS_ALLOW_HEADERS = [ "accept", "accept-encoding", "authorization", "content-type", "dnt", "origin", "user-agent", "x-csrftoken", "x-requested-with", ]
内容的提问来源于stack exchange,提问作者user17817249
相关产品推荐
相关产品推荐

