跨域问题
使用VUE django前后分离,跨域跟django CSRF令牌是个很头疼问题,跨域问题解决方法很多,bing一下就有很多这里先略过,主要讲一下令牌用法,取消令牌检测这里有提到django开发。
django前后分离 CSRF获取及使用
首先要获取CSRF令牌,django中GET请求是不会进行CSRF验证的,这里我们可以创建一个django视图,前端通过GET请求来获取,
Django 配置
1、获取token的视图,这里我写了两个,第一个是前端发送GET请求直接获取,第二个是为了服务端处理登录请求时候 通过后将token以及登录所需的信息一并传递给前端。为什么想了两个,是因为懒,如果都用第一种,后端需要处理一下json数据,就直接复制只传递token字符串,在封装成json给前端。
def get_csrf_token(request):
csrf_token = get_token(request)
print(csrf_token)
return JsonResponse({'csrfToken': csrf_token})
# return csrf_token
def get_csrf_token1(request):
csrf_token = get_token(request)
print(csrf_token)
return csrf_token
2、后端settings配置文件,需要配置以下信息。
CORS_ALLOW_HEADERS = [
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
# 添加其他你需要的请求头,这里比较多
]
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',
'sbh_bly_api.middleware.CustomExceptionMiddleware',
]
# 配置CSRF的信任域,与跨域配置相同,这个很重要,我就是因为这个卡了一天
CSRF_TRUSTED_ORIGINS = [
'http://127.0.0.1:8080', # 确保与前端地址匹配
]
3、VUE前端配置,注意我的VUE项目用的ts,如果用js的请自行转换一下。
1) axios封装,这里对axios请求做了封装 http.ts文件,这里的代码,是将token存储到了 store中,这里是取值“const token = store.state.token” 根据实际项目,和习惯来确定存储位置。
// http.ts
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import store from '@/store';
// 创建 Axios 实例
const instance: AxiosInstance = axios.create({
baseURL: 'http://127.0.0.1:8000',
headers: {
'Content-Type': 'application/json'
},
});
// 请求拦截器
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import store from '@/store';
// 创建 Axios 实例
const instance = axios.create({
baseURL: 'http://127.0.0.1:8000',
timeout: 3000,
headers: {
'Content-Type': 'application/json'
},
});
// 请求相关处理 请求拦截 在请求拦截中可以补充请求相关的配置
// interceptors axios的拦截器对象
instance.interceptors.request.use(config => {
// config 请求的所有信息
// console.log(config);
const token = localStorage.token
config.headers['X-CSRFToken'] = token
return config // 将配置完成的config对象返回出去 如果不返回 请求讲不会进行
}, err => {
// 请求发生错误时的相关处理 抛出错误
Promise.reject(err)
})
instance.interceptors.response.use(res => {
// 我们一般在这里处理,请求成功后的错误状态码 例如状态码是500,404,403
// res 是所有相应的信息
console.log(res)
return Promise.resolve(res)
}, err => {
// 服务器响应发生错误时的处理
Promise.reject(err)
})
export default instance;
2)main.ts配置项,在main中配置开启 axios 请求时发送请求头
import axios from 'axios';
axios.defaults.withCredentials = true;
3)get 请求获取令牌
import axios from '@/http'
const get_token = () => {
console.log("aa")
var post_data = JSON.stringify({
username: "123",
password: "1234"
})
axios({
method: 'GET',
url: axios.defaults.baseURL + '/api/get-csrf-token/',
data: post_data
})
.then(function (response) {
console.log(document.cookie)
// const token = document.cookie.split('=')[1];
//请求成功,处理业务逻辑
console.log(response.data.csrfToken)
// store.state.token =token
// 保存token
store.state.token =response.data.csrfToken
})
.catch(function (error) {
//请求失败,处理业务逻辑
console.log(error)
})
}
如果不成功请留言我们一起解决