Django+vue 解决cookie跨域不携带问题(本地)以及上线后

Django+vue 解决cookie跨域不携带问题

问题描述

使用django session保存用户登入的token,django会将sessionid通过cookie传到浏览器,用户下一次请求的时候带着cookie访问后端
问题:
	1.跨域问题的存在,用户在下一次请求时不会携带cookie,就导致后端无法检验是否已经登入
	2.axios发送请求时,sessionid会变化

直接上解决办法

Django

1.添加第三方库 pip install django-cors-headers

2. 在settings.py 中 INSTALLED_APPS 下 添加 一个 corsheaders 
注册corsheaders
'''
INSTALLED_APPS = [
    ....
    'corsheaders',
]
'''

3.在settings.py 中 Midddleware 中,添加对应的中间件(注意顺序,不然有可能无效。)
'''
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
  	...
]
'''

4.在settings.py 中任意位置写入
SESSION_EXPIRE_AT_BROWSER_CLOSE = True  # 会话cookie可以在用户浏览器中保持有效期。 False---session 在一段时间不活动后过期。True:关闭浏览器,则Cookie失效。
SESSION_COOKIE_SAMESITE = None
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CSRF_COOKIE_SAMESITE = None
CSRF_COOKIE_SECURE = False
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)

CORS_ALLOW_HEADERS = (
    'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'Pragma',
    'Cookie',
)

VUE

 1. 首先我们应该知道,前端axios在本地发送的请求如果你不把路径写全,它都是会默认加上自己项目所在的端口,就比如说:
    axios.get('/login')
	axios.get('/hello')
    当我点击发送按钮之后,以上两行代码实际为:
 	http://localhost:8080/login
	http://localhost:8080/hello
    其中 localhost:8080 就是自己项目所在的地址了。实际前端就会根据以上的地址来访问后端程序了。
2. 跨域,什么是跨域呢?
首先,明白什么是同源策略?同源就是指 协议、域名、端口 都要相同,其中任何一个不同都会出现跨域。例如:
http://www.baidu.com:8000
// http 是协议
// www.baidu.com 是域名
// 8000 是端口
'''
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

这里说明一下,无法跨域是浏览器对于用户安全的考虑。是浏览器的锅。

同源策略限制了一下行为: Cookie、LocalStorage 和 IndexDB 无法读取 DOM 和 JS 对象无法获取 Ajax请求发送不出去。

前后端分离的模式下,前后端的域名是不一致的,所以就会出现跨域问题。
'''

当我们开发完前端一个功能之后,需要运行调试 ,通常前后端分离情况下,两套程序都运行起来之后,肯定会出现 协议、域名、端口不一致的形况吧。

那么前端调用后端接口时就会产生跨域问题。怎么办呢?就需要代理(proxy)出场了。

proxy配置

假如我现在想请求后端的 一个接口 例如:http://www.aaabbbccc.com/login ,这样我们应该怎样配置代理服务器呢?

如果没有vue.config.js,在package.json同级目录下创建
// vue.config.js
module.exports = {
  devServer: {  //开启代理服务器
    proxy:{
      "/api": {  // /api是自行设置的请求前缀,按照这个来匹配请求,有这个字段的请求,就会走到代理来。
          target: "http://www.aaabbbccc.com", // 需要代理的域名,目标域名,会替换掉匹配字段之前的路径
           ws: false, // 是否启用websockets
          changeOrigin: true, //是否跨域
          pathRewrite: {  //重写匹配的字段,如果不需要放在请求路径上,可以重写为""
              "^/api": ""
          }
      },
  },
}
              
              
              
 //vue cli2 .0 的放在 config文件夹中的index.js  中
    dev: {
    proxyTable:{
      "/api": {
          target: "http://www.aaabbbccc.com", // 需要代理的域名
           ws: false, // 是否启用websockets
          changeOrigin: true, //开启跨域
          pathRewrite: {  //重写请求路径上匹配到的字段,如果不需要在请求路径上,重写为""
              "^/api": "",
             
          }
      },
  },
  }
    
'''
以上配置中,我配置了一个 /api,只有包含这个请求的路径才会走代理,例如:
http://localhost:8080/api/login //这个就可以走代理

http://localhost:8080/login //这个就不行
'''

二次封装axios

可以看到,要想所有的请求都进入代理中,就必须包含/api这个路径,那么我可以对axios进行二次封装,给所有的请求加这个前缀,代码如下:

const requests = axios.create({
  
  baseURL:'/api', // 设置通用请求的地址前缀

  withCredentials : true //让ajax携带cookie并且保持sessionid一致
  
  timeout:10000  //请求超时的时间
});
export default requests  //将requests实例,对外进行暴露

发送请求可以写为:
requests.get('/login').then((response) => {})
requests.get('/getlist').then((response) => {})
requests.get('/user/hello').then((response) => {})


此时我发送的请求就是:
http://localhost:8080/api/login

http://localhost:8080/api/getlist

http://localhost:8080/api/user/hello


通过代理的 target属性 加工之后就是 :
http://www.aaabbbccc.com/api/login

http://www.aaabbbccc.com/api/getlist

http://www.aaabbbccc.com/api/user/hello


就是把 /api 之前的路径 修改成了 target里配置的 目标服务器的路径。

在通过 pathRewrite属性 将 /api 替换为空 为:
http://www.aaabbbccc.com/login

http://www.aaabbbccc.com/getlist

http://www.aaabbbccc.com/user/hello
这样就可以访问到后端的对应接口了。

不想用二次封装可以使用简单配置axios,但是proxy配置还是相同

在main.js中

import axios from 'axios'

axios.defaults.withCredentials = true; //让ajax携带cookie并且保持sessionid一致
axios.defaults.baseURL = '/api' //初始化基础地址
Vue.prototype.$axios = axios;

'''
  使用时 
  this.$axios.post('url',{data}).then(res=>{
    .....
  })
'''

上线后

'''
  需要注意一点vue的代理在上线后就会失效
  在vue.config.js中配置了proxy跨域后执行npm run build打包部署到服务器上会报跨域问题,为什么会报错呢?因为编译打包后,前端页面成为了单独的静态资源,代理服务器devServer.proxy被抽离出去了。

  也就是说,devServer.proxy不会一起打包到dist文件夹下,所以相当于我们没有配置代理服务器!!

  怎么解决呢?资源要被访问,那必须要有一个代理服务器来装载它。我们部署上线最常见的就是使用nginx进行反向代理,只需要修改nginx配置文件即可。
'''
解决办法:
  使用nginx反向代理后端
  	location /api/ {
			proxy_pass http://00.00.00.00:8889/; # 00.00.00.00 修改为服务器的ip地址
	}

本文作者:春游去动物园

本文链接:https://www.cnblogs.com/chunyouqudongwuyuan/p/17167882.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   春游去动物园  阅读(579)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开
  1. 1 生分 川青
生分 - 川青
00:00 / 00:00
An audio error has occurred.

生分 - 川青

词:莎子

曲:邵翼天

编曲:林亦

混音:罗杨轩

吉他:林亦

制作人:谢宇伦

监制:曾炜超/陈显

策划:+7

统筹:黄染染

出品:漫吞吞文化

『酷狗音乐人 • 星曜计划』

全方位推广,见证星力量!

「版权所有未经许可 不得商业翻唱或使用」

我们怎么变得那么生分

用了几年也没解开疑问

有些事你不提我也不问

在陌生与熟悉间找平衡

有些话一开口会伤人

有些话一开口会伤人

所以我选择默不作声

所以我选择默不作声

爱一个人

若甘愿陪衬

甘愿牺牲

也许换个名分

也不是没可能

我不怕在爱里做个蠢人

我不怕在爱里做个蠢人

也不怕爱过之后再分

也不怕爱过之后再分

爱一个人

有万种身份

万种可能

只是没想到

我们最后友人相称

我们怎么变得那么生分

我们怎么变得那么生分

连说话都要掌握好分寸

怕不注意流言

见缝插针

怕不小心我们

成陌生人

我们怎么变得那么生分

用了几年也没解开疑问

有些事你不提我也不问

在陌生与熟悉间找平衡

有些话一开口会伤人

有些话一开口会伤人

所以我选择默不作声

所以我选择默不作声

爱一个人

若甘愿陪衬

甘愿牺牲

也许换个名分

也不是没可能

我不怕在爱里做个蠢人

我不怕在爱里做个蠢人

也不怕爱过之后再分

也不怕爱过之后再分

爱一个人

有万种身份

万种可能

只是没想到我们最后

友人相称

我们怎么变得那么生分

连说话都要掌握好分寸

怕不注意流言见缝插针

怕不小心我们成陌生人

我们怎么变得那么生分

用了几年也没解开疑问

有些事你不提我也不问

在陌生与熟悉间找平衡

我们怎么变得那么生分

我们怎么变得那么生分

连说话都要掌握好分寸

怕不注意流言见缝插针

怕不小心我们成陌生人

我们怎么变得那么生分

用了几年也没解开疑问

有些事你不提我也不问

在陌生与熟悉间找平衡