Angular与Django跨域报错:请求资源无Access-Control-Allow-Origin头
Django + Angular 跨域CORS错误排查与解决(添加自定义JWT中间件后触发)
问题场景
- Angular本地服务(http://localhost:4200)请求Django后端接口(http://127.0.0.1:8000/api/user/)时,出现CORS错误:
请求资源缺少Access-Control-Allow-Origin头 - 已在Django的
settings.py中配置corsheaders,设置CORS_ORIGIN_ALLOW_ALL=True、CORS_ALLOW_CREDENTIALS=True,并将CorsMiddleware加入中间件列表 - 此前登录、注册接口无跨域问题,添加自定义JWT验证中间件后出现该错误
- Postman测试接口正常,Angular端
validateToken方法已设置JWT请求头;启用Chrome跨域插件后,错误变为预检请求无HTTP成功状态码
排查与解决步骤
1. 调整中间件执行顺序
CorsMiddleware必须**优先于所有业务中间件(包括自定义JWT中间件)**执行。如果JWT中间件先处理请求,会在预检OPTIONS请求时直接返回未授权错误,导致CORS头还未被添加到响应中。
修改settings.py的MIDDLEWARE配置:
MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 放在最顶部 'django.middleware.security.SecurityMiddleware', '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', 'your_custom_app.middleware.YourJWTMiddleware', # 自定义JWT中间件后置 ]
2. 让自定义JWT中间件放行OPTIONS预检请求
浏览器发送的OPTIONS预检请求不需要携带JWT Token,你的自定义中间件要跳过这类请求的验证逻辑,直接放行。
修改自定义JWT中间件代码:
from django.utils.deprecation import MiddlewareMixin class JWTMiddleware(MiddlewareMixin): def process_request(self, request): # 直接放行OPTIONS预检请求 if request.method == 'OPTIONS': return None # 以下是你的JWT Token验证逻辑 # ...
3. 检查预检请求的响应状态码
在浏览器网络面板中查看OPTIONS请求的响应状态码,确保返回200 OK或204 No Content,而非401 Unauthorized或403 Forbidden。如果状态码异常,说明JWT中间件没有正确放行OPTIONS请求。
4. 完善Angular端请求配置
由于你开启了CORS_ALLOW_CREDENTIALS=True,Angular请求必须携带withCredentials属性:
import { HttpClient, HttpHeaders } from '@angular/common/http'; // ... validateToken() { const token = localStorage.getItem('auth_token'); const headers = new HttpHeaders({ 'Authorization': `Bearer ${token}` }); return this.http.get('http://127.0.0.1:8000/api/user/', { headers: headers, withCredentials: true // 必须添加此配置 }); }
内容的提问来源于stack exchange,提问作者Rubén Plazas
相关产品推荐
相关产品推荐

