Django 跨域配置指南:3 种方法解决 CORS 问题,附前端 Vue 示例
在前后端分离项目中,你是否遇到过这样的报错:“Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/' from origin 'http://localhost:8080' has been blocked by CORS policy”?这就是跨域资源共享(CORS) 限制导致的 —— 浏览器为了安全,会拦截不同域名 / 端口的请求
本文将详细讲解 Django 中配置 CORS 的 3 种方法,从推荐的第三方库到手动配置,再到个别视图的单独处理,最后附上 Vue 前端配合示例,帮你彻底解决跨域问题
一、什么是 CORS?为什么需要配置?
简单来说,CORS 是浏览器的一种安全机制:当前端(如 Vue 跑在 localhost:8080)向后端(Django 跑在 127.0.0.1:8000)发送请求时,由于域名 / 端口不同,浏览器会先发送一个 “预检请求(OPTIONS)”,确认后端允许跨域后才会发送真实请求
如果 Django 没有配置 CORS 规则,就会拒绝这个预检请求,导致前端请求失败
二、方法一:使用 django-cors-headers(推荐)
这是 Django 社区最常用、最稳定的跨域解决方案,支持丰富的配置项,兼顾开发效率和生产安全
步骤 1:安装依赖包
打开终端,执行 pip 安装命令:
pip install django-cors-headers
步骤 2:修改 settings.py 配置
这一步是核心,需要配置 “注册应用”“添加中间件” 和 “CORS 规则” 三部分,注意中间件顺序很重要
2.1 注册应用到 INSTALLED_APPS
在 settings.py 的 INSTALLED_APPS 列表中添加 corsheaders:
# settings.py
INSTALLED_APPS = [
# ... 其他已有的应用(如 django.contrib.admin、django.contrib.auth 等)
'corsheaders', # 新增:注册 cors 应用
# ... 其他应用
]
2.2 添加中间件到 MIDDLEWARE
将 CorsMiddleware 放到 尽可能靠前的位置(建议在 SecurityMiddleware 之前),因为中间件是按顺序执行的,CORS 处理需要优先于其他请求处理:
# settings.py
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 新增:CORS 中间件(放最前面)
'django.middleware.security.SecurityMiddleware', # Django 自带安全中间件
'django.contrib.sessions.middleware.SessionMiddleware', # 会话中间件
# ... 其他中间件(如 CommonMiddleware、CsrfViewMiddleware 等)
]
2.3 配置 CORS 核心规则
根据环境(开发 / 生产)配置不同的规则,关键配置项如下:
# settings.py
# -------------------------- 1. 允许的域名(核心)--------------------------
# 开发环境:允许所有域名(方便调试,生产环境绝对不能用!)
CORS_ALLOW_ALL_ORIGINS = True # 开发用,生产注释掉
# 生产环境:明确指定允许的域名(推荐,仅开放需要的域名)
# CORS_ALLOWED_ORIGINS = [
# "https://yourdomain.com", # 你的正式域名
# "https://www.yourdomain.com", # 带 www 的子域名
# "http://localhost:8080", # 若生产环境有前端调试需求,可临时加
# ]
# 进阶:允许符合正则的子域名(如 blog.yourdomain.com、admin.yourdomain.com)
# CORS_ALLOWED_ORIGIN_REGEXES = [
# r"^https://\w+\.yourdomain\.com$", # \w+ 匹配任意字母/数字/下划线
# ]
# -------------------------- 2. 允许的 HTTP 方法 --------------------------
# 默认已包含 GET/POST/PUT/DELETE 等,可按需扩展(一般不用改)
CORS_ALLOW_METHODS = [
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT",
]
# -------------------------- 3. 允许的请求头 --------------------------
# 若前端需要传自定义头(如 Token、X-CSRFToken),需在这里添加
CORS_ALLOW_HEADERS = [
"accept",
"authorization", # 用于 JWT Token 等认证
"content-type", # 用于 POST/PUT 的 JSON 数据
"user-agent",
"x-csrftoken", # Django CSRF 防护需要
"x-requested-with",
]
# -------------------------- 4. 允许携带凭证(如 Cookies、Token)--------------------------
# 若前端需要传 Cookies 或带认证信息,必须设为 True
CORS_ALLOW_CREDENTIALS = True
# -------------------------- 5. 预检请求缓存时间 --------------------------
# 浏览器发送预检请求后,会缓存结果,避免每次请求都发预检(单位:秒)
CORS_PREFLIGHT_MAX_AGE = 86400 # 1 天(默认 86400,可按需调整)
三、方法二:手动配置自定义中间件
如果不想依赖第三方库,可以自己写一个中间件来添加 CORS 响应头。这种方法灵活性高,但需要手动处理所有规则,适合简单场景
步骤 1:创建中间件文件
在你的 Django 应用(如 myapp)下新建 middleware.py 文件:
# myapp/middleware.py
class CorsMiddleware:
def __init__(self, get_response):
# 初始化:接收 Django 的 get_response 函数(必须)
self.get_response = get_response
def __call__(self, request):
# 1. 先处理请求,得到响应对象
response = self.get_response(request)
# 2. 手动添加 CORS 响应头
# 允许的域名:生产环境替换为具体域名(如 "https://yourdomain.com"),不要用 * 带凭证
response["Access-Control-Allow-Origin"] = "*"
# 允许的 HTTP 方法
response["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
# 允许的请求头(若前端传自定义头,需在这里添加)
response["Access-Control-Allow-Headers"] = "Content-Type, Authorization, X-CSRFToken"
# 允许携带凭证(若需要,设为 "true",此时 Origin 不能用 *)
response["Access-Control-Allow-Credentials"] = "true"
# 3. 返回添加了头的响应
return response
步骤 2:注册自定义中间件
和方法一类似,在 settings.py 的 MIDDLEWARE 中添加自定义中间件,位置同样要靠前:
# settings.py
MIDDLEWARE = [
'myapp.middleware.CorsMiddleware', # 新增:自定义 CORS 中间件
'django.middleware.security.SecurityMiddleware',
# ... 其他中间件
]
四、方法三:在视图中单独处理(个别场景)
如果只有少数几个视图需要跨域(比如开放给第三方的 API),没必要全局配置,直接在视图中手动添加响应头即可
示例:基于函数的视图
# myapp/views.py
from django.http import JsonResponse
def open_api_view(request):
# 1. 处理业务逻辑(如返回数据)
data = {"status": "success", "message": "这是开放的跨域 API"}
response = JsonResponse(data)
# 2. 手动添加 CORS 头(仅对当前视图生效)
response["Access-Control-Allow-Origin"] = "https://thirdparty.com" # 仅允许第三方域名
response["Access-Control-Allow-Methods"] = "GET, OPTIONS" # 仅允许 GET 和预检
response["Access-Control-Allow-Headers"] = "Content-Type"
# 3. 返回响应
return response
示例:基于类的视图
# myapp/views.py
from django.views import View
from django.http import JsonResponse
class OpenApiView(View):
def get(self, request):
data = {"status": "success", "message": "类视图的跨域响应"}
response = JsonResponse(data)
# 添加 CORS 头
response["Access-Control-Allow-Origin"] = "https://thirdparty.com"
return response
五、前端配合:Vue + Axios 配置
跨域是前后端配合的问题,后端配置好后,前端需要确保请求参数正确(尤其是携带凭证时)
示例:Axios全局配置
在 Vue 项目的 main.js 或请求工具文件中配置:
// src/main.js 或 src/utils/request.js
import axios from 'axios';
// 1. 配置后端基础 URL(Django 服务地址)
axios.defaults.baseURL = 'http://127.0.0.1:8000';
// 2. 允许携带凭证(若后端 CORS_ALLOW_CREDENTIALS = True,必须设为 true)
axios.defaults.withCredentials = true;
// 3. 挂载到 Vue 原型(方便组件中使用)
Vue.prototype.$axios = axios;
示例:发送具体请求
// 在 Vue 组件中
export default {
methods: {
fetchData() {
this.$axios.get('/api/data/') // 后端接口
.then(response => {
console.log("跨域请求成功:", response.data);
})
.catch(error => {
console.error("跨域请求失败:", error);
});
},
submitData() {
const postData = { name: "测试", value: "123" };
this.$axios.post('/api/submit/', postData)
.then(response => {
console.log("POST 请求成功:", response.data);
});
}
}
};
六、生产环境必须注意的 4 点
1、绝对禁止使用 CORS_ALLOW_ALL_ORIGINS = True
开发环境用它方便调试,但生产环境会暴露所有接口,存在安全风险,必须用 CORS_ALLOWED_ORIGINS 指定具体域名
2、携带凭证时,Access-Control-Allow-Origin 不能用 *
若 CORS_ALLOW_CREDENTIALS = True,CORS_ALLOWED_ORIGINS 必须写具体域名(如 https://yourdomain.com),不能用通配符 *,否则浏览器会拒绝响应
3、限制允许的方法和头部
只开放业务需要的 HTTP 方法(如不需要 DELETE 就删掉)和请求头,避免不必要的暴露
4、HTTPS 环境下的域名配置
生产环境若用 HTTPS,CORS_ALLOWED_ORIGINS 中的域名必须带 https://(如 https://yourdomain.com),不能用 HTTP
七、常见问题及解决方案
问题 1:预检请求(OPTIONS)失败
现象:前端报错 “Preflight response is not successful”
原因:后端没有正确处理 OPTIONS 请求(预检请求)
解决:
- 方法一(推荐):用
django-cors-headers,它会自动处理 OPTIONS 请求,无需手动写逻辑 - 方法二(自定义中间件):确保中间件对所有请求(包括 OPTIONS)都添加了 CORS 头
问题 2:携带凭证时请求被拦截
现象:前端 withCredentials: true,后端 CORS_ALLOW_CREDENTIALS = True,但报错 “Credentials flag is true, but Access-Control-Allow-Origin is not set”
原因:Access-Control-Allow-Origin 用了 *,但携带凭证时不允许通配符
解决:在 settings.py 中用 CORS_ALLOWED_ORIGINS 替换 CORS_ALLOW_ALL_ORIGINS,指定具体域名
问题 3:自定义请求头不被允许
现象:前端传自定义头(如 X-Token),报错 “Request header field x-token is not allowed by Access-Control-Allow-Headers”
原因:后端 CORS_ALLOW_HEADERS 中没有包含这个自定义头
解决:在 settings.py 的 CORS_ALLOW_HEADERS 中添加 x-token(注意大小写一致)
八、总结
1、推荐场景:90% 的前后端分离项目用 方法一(django-cors-headers),配置简单、功能全面,兼顾开发和生产
2、特殊场景:不想依赖第三方库用 方法二(自定义中间件),少数视图跨域用 方法三(视图单独处理)
3、核心原则:生产环境优先保证安全,明确指定允许的域名、方法和头部,不滥用通配符
按照本文的步骤配置,你就能顺利解决 Django 的跨域问题,让前后端流畅通信!
更多推荐

所有评论(0)