python+vue+django前后端分离项目实战,Vue项目前后端分离下的前端鉴权方案
python+vue+django前后端分离项目实战,Vue项目前后端分离下的前端鉴权方案详细介绍
本文目录一览: django+vue前后端分离项目部署
后端用的drf,使用的是uwsgi+nginx
进入服务器项目文件目录下,我的django项目放在了“/usr/myProjects/”目录下了。在manage.py同级目录下创建uwsgi.ini文件,配置如下:
测试效果命令:
如果访问:xxx.xxx.xxx.xx:8000 成功, 则uwsgi.ini配置成功
我的nginx.conf所在位置是“/etc/nginx/nginx.conf”
配置文件如下:
1、第一行
主要就是给nginx加权限,vue部署后使用history路由时会去掉地址后面的‘#’号,打包部署后不加权限会有bug。
2、如配置所示,有两个Server,分别部署了前端服务,和后端服务,值得注意的是两个Server用的是同一个服务器,监听的端口不同。
3、vue部署需要注意的是反向代理地址:
以及后面的端口问题
4、后端的Server需要注意location中的uwsgi_pass 后面的端口号要和uwsgi.ini中配的相同,否则监听不到
5、后端跨域问题。如果遇到跨域需要自己网上找配置,我的没遇到,可能是因为我在django的settings中配置了跨域。
6、django-suit后台管理样式崩了,需要改,但是api可以正常访问,这个有空再说
7、我开始后台监听的是8008端口,vue前端监听的是80端口,这样前端显示好看。然而问题出现了,虽然后台api可以正常访问,vue的本地开发环境也能正常运行且文字、图片资源均显示正常,但是前端vue打包线上部署后,文字信息显示正常,图片信息缺失8008端口,导致显示不出来。为图方便我选择了前端监听8008端口,后端监听80,部署后显示正常。原因不太清楚///////有空再说吧。
8、不要问我为啥都前后端分离了还部署到一个服务器上?穷,而且只是测试,没必要
9、此文仅适合入门
关于django后台admin(suit)缺失的修改(参考:django中文网: https://www.django.cn/article/show-4.html )
在环境中进入项目目录,需要收集css样式,在终端输入命令:
接下来你就回发现static文件中包含了css文件,此时再打开网站,样式显示正常
uWSGI 通过 xxx.ini 启动后会在相同目录下生成一个 xxx.pid 的文件,里面只有一行内容是 uWSGI 的主进程的进程号。
关于uwsgi,进入同届目录下
教训
获取不到环境,那就指定环境
另外:记得重启uwsgi,重启Nginx,实在不行就先把监听的端口kill掉再重启
暴力删端口:fuser -k 80/tcp
netstat -aptn命令行,查看所有开启的端口号
netstat -ntlp | grep 80 查看具体的端口是否使用
ps -ef | grep uwsgi 查看是否有uwsgi端口存在
如何进行前后端分离
前后端分离的意思是,前后端只通过JSON来交流,组件化、工程化不需要依赖后端去实现。
在开发阶段,前后端工程师约定好数据交互接口,实现并行开发和测试;在运行阶段前后端分离模式需要对web应用进行分离部署,前后端之前使用HTTP或者其他协议进行交互请求。
前后端分离,那后端就不应该修改前端项目文件,并且前后端交互都应通过ajax执行。所以,后端只需要提供api,前端在html调用api即可。
首先:软件系统架构的前后端分离更多是在近几年伴随互联网的盛行为提高前端与后端交互的响应速率,提升用户的体验进行衍生出了前后端分离架构。如:Vue、NodeJS与微服务架构结合。
)webpack设置proxy,这个通过webpack文档或GOOGLE一下可以解决。
在node中vue项目如何实现前后端分离
其实基于vue.js+node.js构建的开源博客系统有很多,下面这篇文章主要给大家介绍了关于node vue项目开发之前后端分离的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友下面来一起看看吧。前言本文主要介绍了关于node vue前后端分离的相关资料,分享出来供大家参考学习,下面随着小编来一起学习学习吧。node vue项目开发最近看了近一周的vue开发,有诸多感触,我之前接触过react、angular所以特别想学学久仰大名的vue。学习半天以后发现,接触到的东西多了,学习起来就是容易很多,vue的指令我能个联想到angular的指令,vue组件化设计类似于react的组件化设计,包括一些router的设置跟react里的路由或者nodejs里的路由都差不多,vuex更是根据redux、flux改写的,虽然我还搞不太明白怎么用,至于vue的模板渲染,跟expres渲染ejs没有太大的区别。使用vue可以完全脱离jq,虽然我还没感受到不用jq有什么神奇的赶脚,但是我觉得这种双向数据绑定的还是挺方便的,此文档用来记录我学习vue的一些新的知识和想法。指令v-bind 主要用于动态绑定DOM元素属性,即元素属性实际的值是 有vm实例中的data属性提供的。v-model 主要对表单元素进行双向数据绑定,在修改表单元素的值时,实例vm中对应的vm对应的属性也同时更新。v-if,v-show,v-else这几个指令来说明模板和数据间的逻辑关系 v-if和v-else的作用是根据数值来判断是否输出该dom元素,以及包含的子元素。 eg:
yes
当vm实例中的data.yes=true时,模板引擎会编 译这个dom节点,输出
yes
值得注意的是:v-else要紧跟v-if否则不起作用。 v-show与v-if的效果差不多,都是通过判断真假显示内容,唯一不同的是,v-show不显示的时候是display:none,也就是保留了dom节点,但是v-if不会。v-for 用于列表渲染,可以循环遍历数组和对象,注意v-for="b in 10"目前指的是1-10的迭代v-on 事件绑定,简写@:v-text
相当于innerText,与{{msg}}相比,避免了闪现的问题。v-HTML 类似于innerHTML,也可以避免闪现v-el 这个指令相当于给dom元素添加了个索引,例如
this is a test
,如果想获取当前dom里的值,可以vm.$els.demo.innerText ,注意:html不区分大小写,驼峰式的写法会自动转成小写,可以通过-的方式转换成大写。v-ref 与v-el类似 通过vim.$refs访问v-pre 跳过编译这个元素v-cloak 感觉没啥用v-once新增内置指令,用于标明元素或组件只渲染一次。模板渲染1、v-for 主要用于列表渲染,讲根据接受到的数组重复渲染v-for绑定到的dom元素及内部子元素,并可以通过设置别名的方式,获取数组内数据渲染到节点中。eg:
- {{item.title}}
- {{item.description}}
2、v-for内置$index变量,可以在调用v-for的时候调用,例如
3、修改数据直接修改数组可以改变数据不能直接改变数组的情况 1.vm.items[0]={} , 这种情况下无法修改,解决:vm.item.$set(0,{})或者vm.$set('item[0]',{}) 2.vm.item.length=04、v-for遍历对象,可以使用(key,value)的形式自定义key变量。
5、template标签用来作为模板渲染的跟节点,但是渲染出来不存在此节点事件绑定与监听v-on可以绑定实例属性methods中的方法作为事件的处理器,v-on:后面可以接受所有的原生事件名称。简写 @:可以绑定methods函数,也支持内联js,但是仅限一个语句。绑定methods函数和内联js都可以获取原生dom元素,event.绑定多个事件时,为顺序执行。ui组件 饿了吗使用指南安装npm install cnpm install element-ui --save-dev引入文件main.jsimport ElementUI from 'element-ui'import 'element-ui/lib/theme-chalk/index.css'Vue.use(ElementUI, { size: 'small' })使用在components文件夹下新建一个页面,从饿了吗找到自己喜欢的组件,比如走马灯 Carousel.vue 把代码复制到这个页面在需要的此组件的文件下,比如APP.vue里import Carousel from './components/Carousel'export default { name: 'app', components: { //components加s Carousel: Carousel }}在模板里载入组件
这样就可运行了前后端分离习惯了用node做全栈开发,现在用vue-webpack做前端开发,node做后端开发也挺爽的,前后端实现了分离。启动后端接口cd backcnpm installnpm run dev启动前端服务器cd frontcnpm installnpm start进入登录页面,点击登录,控制台打印访问成功的信息,并成功跳转到helloworld页面前后端通信vue-resource安装vue-resource 并在main.js中引用import VueResource from 'vue-resource'Vue.use(VueResource)在config/index.js 配置 proxyTable代理服务器proxyTable: { '/api/**': { target: 'http://localhost:3000', pathRewrite: { '^/api': '/api' } }}使用this.$http.get('api/apptest') .then((response) => { // 响应成功回调 console.log(response) }).catch(e => { // 打印一下错误 console.log(e) }) }缺点:在开发环境下没有问题,但是在生产环境下请求后端接口不成功axios首先配置axios,在src下新建一个http.jsimport axios from ‘axios'axios.defaults.timeout = 5000axios.defaults.baseURL = 'http://localhost:3000'axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'export default axios在main.js中引入import axios from './http'Vue.prototype.axios = axiosnew Vue({ el: '#app', router, axios, template: '
', components: { App }})使用get方法login () { // 获取已有账号密码 this.axios.get('/apptest') .then((response) => { // 响应成功回调 console.log(response) // this.$router.go({name: 'main'})// 不管用 this.$router.push({name: 'HelloWorld'}) }).catch(e => { // 打印一下错误 console.log(e) })}post方法register () { console.log(this) // 获取已有账号密码 let params = { user: this.userinfo.account, password: this.userinfo.password, directionId: this.userinfo.directionId } this.axios.post('/signup', params) .then((response) => { // 响应成功回调 console.log(response) }).catch(e => { // 打印一下错误 console.log(e) })}生产环境路径问题在生产环境下发现打包以后路径不对,修改config下的index.jsbuild: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: './', //原来是 assetsPublicPath: '/'上面是我整理给大家的,希望今后会对大家有帮助。相关文章:在JS中如何实现网页自动秒杀点击(详细教程)在node中如何实现http小爬虫在angular2中有关Http请求原理(详细教程)使用VueAwesomeSwiper容易出现的问题?使用Node.js爬虫如何实现网页请求如何使用VUE2.X过滤器
前后端分离怎么实现
前后端分离实现方式:
1、前后端分离的概念就是“调接口与前端展示数据跟数据交互”,后端给前端专门写接口,至于数据格式自己定,如果处理的好未必一定说是要用json,只是json是目前数据交互上比较好的。
2、接口数据都有了,那么接下来就是前端数据的展示,前提你要有自己的数据解析库。因为这样数据展示就容易。
3、可以自己封装,但现有相对好的数据引擎库有AngularJS、vueJS、Template7等,同时html模板引擎也需要,这样写页面就可以模块化开发。
4、可以自己写,也可以用现成的,比如jade、React等。数据展示好了,最后就是数据交互了,用ajax就可以了,所以必须得对ajax了解。
5、至于其他的所谓跨域问题,那都是可以跟后端协商的,一般都是后端需要处理,要是用到jsonp格式,前端就要协助一下写个调用函数就可以。
前后端为什么要分开写
大家都知道,通常公司都会要求我们前端和后端分开来写,为什么要这么做呢?这次给大家带来前后端为什么要分开写,下面就是实战案例,一起来看一下。如果你没有尝试过前后端分离的工作流程,那么可以先试想一下这样的流程改变:把流程从PM:“我要这个功能”后端:“这个先找前端做个模板”前端:“模板做完了”后端:“我来对接一下,这里样式不对”前端:“我改完了”后端:“功能交付”PM:“春节要加这个活动”后端:“这个先找前端改个模板”前端:“模板做完了”后端:“我来对接一下,这里样式不对”前端:“我改完了”后端:“功能交付”变成PM:“我要这个功能”前端:“我要接口”后端:“接口完成了”前端:“我来对接一下,功能交付”PM:“春节要加这个活动”前端:“需要增加接口”后端:“接口完成了”前端:“我来对接一下,功能交付”由此可见,前后端分离的主要概念就是:后台只需提供API接口,前端调用AJAX实现数据呈现。现状与分歧作为一名前端开发人员,我们应该尝试一些新颖的技术,完善每一个细节性的问题,不断突破自我。虽然前后端分离已经算不上什么新颖的技术或思路,但是目前很多后台开发人员甚至前端开发人员都没有接触过。据我个人的了解,如果在一个部门里,部门人员全是后台开发人员,前端的一些页面也是由后台人员完成的,那么前后端分离对于他们而言可能是一片未知的领域,项目大多是前后端强耦合的,甚至不存在前端的概念。在不重视前端的公司或部门,不了解前后端分离这也无可厚非。大多的创业型公司,一个部门就一两个前端,而且一人负责几个项目,很少有合作完成一个项目的时候。因为没有什么标准可言(这里的标准指的是代码组织结构),所以就是前端人员切好图写好页面扔给后端,以后端代码结构为标准。虽然一些公司有前后端分离的意识,但都不知该如何去实践。在那时,部门的后台人员认为前后端分离就是后台不再需要写HTML和JS了,可以交给前端来做了,然而这只能叫做前后端分工。以上讲述的是一种情况: 不了解前后端分离,也不知如何去实践的。下面还有一种情况:了解前后端分离,但不想去尝试的。针对第二种情况,很多人也做过相应的解释,其实这就涉及到“前后端分离的利弊”问题。很多后台人员会认为自己所做的那一套没有问题,即便后台套用前端html也是司空见惯,一直是大势所趋,后台MVC框架也是这么推荐使用的,很合理。这时候前端开发人员在部门中的话语权往往是不够的,或者认为后台开发人员的意见永远是对的,没有主观性。相反,也有可能是后台开发人员非常推荐前后端分离,而前端开发人员不想去实践的。这时候前端会认为后台开发人员在瞎折腾,之前前后端不分离项目做起来都很顺利,分离了反而会给自己带来额外的工作量和学习成本,而这就取决于前端的技术能力和见识了。当然,这也是我个人认为的前后端分离所存在的一些现状和分歧所在。场景与要求对于前后端分离的应用场景,不是所有的场景都适合,但是大多数项目都能够通过前后端分离来实现。由于我主要从事企业级后台应用的前端开发工作,个人认为对于后台应用的开发来说,前后端分离带来的利是远大于弊的。大多数后台应用我们都可以做成SPA应用(单页应用),而单页应用最主要的特点就是局部刷新,这通过前端控制路由调用AJAX,后台提供接口便可以实现,而且这样的方式用户体验更加友好,网页加载更加快速,开发和维护成本也降低了不少,效率明显提升。同样的,在展示类网站和移动APP页面中前后端分离也同样试用。前后端不分离的情况下,服务端要单独针对Web端做处理,返回完整HTML,这样势必增加服务端的复杂度,可维护性差,而web端需要加载完整的HTML,一定程度上影响网页性能,这对于移动端性能为王的地方非常的不友好。随着前端技术的发展和迭代,前端MVC框架应运而生,利用目前主流的前端框架,如React、Vue、Angular等我们可以轻松的构建起一个无需服务器端渲染就可以展示的网站,同时这类框架都提供了前端路由功能,后台可以不再控制路由的跳转,将原本属于前端的业务逻辑全部丢给前端,这样前后端分离可以说是最为彻底。下面是一段前端控制路由的代码:'use strict'export default function (router) { router.map({ '/': { component: function (resolve) { require(['./PC.vue'], resolve) } }, '/m/:params': { component: function (resolve) { require(['./Mobile.vue'], resolve) } }, '/p': { component: function (resolve) { require(['./PC.vue'], resolve) }, subRoutes: { '/process/:username': { component: function (resolve) { require(['./components/Process.vue'], resolve) } } } } })}前后端分离的实现对技术人员尤其是前端人员的要求会上升一个层次,前端的工作不只是切页面写模板或是处理一些简单的js逻辑,前端需要处理服务器返回的各种数据格式,还需要掌握一系列的数据处理逻辑、MVC思想和各种主流框架。优势与意义对于前后端分离的意义我们也可以看做是前端渲染的意义,我主要总结了下面四点:彻底解放前端前端不再需要向后台提供模板或是后台在前端html中嵌入后台代码,如:
--请选择所属业务-- {% for p in p_list %} {{ p }} {% endfor %}这是前后端耦合的,可读性差。
--请选择所属业务--
上面是前端渲染的一段代码,前端通过AJAX调用后台接口,数据逻辑放在前端,由前端维护。提高工作效率,分工更加明确前后端分离的工作流程可以使前端只关注前端的事,后台只关心后台的活,两者开发可以同时进行,在后台还没有时间提供接口的时候,前端可以先将数据写死或者调用本地的json文件即可,页面的增加和路由的修改也不必再去麻烦后台,开发更加灵活。局部性能提升通过前端路由的配置,我们可以实现页面的按需加载,无需一开始加载首页便加载网站的所有的资源,服务器也不再需要解析前端页面,在页面交互及用户体验上有所提升。降低维护成本通过目前主流的前端MVC框架,我们可以非常快速的定位及发现问题的所在,客户端的问题不再需要后台人员参与及调试,代码重构及可维护性增强。心得与体会:一路走来,项目一个接着一个,从一开始的后台控制路由、后台渲染页面到现在的前端控制路由、前端渲染数据,工作流程和方式都发生了很大的变化。每当遇到下面情形的时候,我都会为前后端分离带来的优势而感慨一番:1、项目一开始制作前端页面的时候,我不再需要后台给我配置服务器环境了2、项目的前端文件可以在需要调用后台接口的时候丢进服务器就好了,完全不需要事先放进去3、增加一个项目页面需要配置路由的时候不再需要让后台同事给我加了,自己前端搞定4、前端文件里不再掺杂后台的代码逻辑了,看起来舒服多了5、页面跳转比之前更加流畅了,局部渲染局部加载非常快速6、页面模板可以重复使用了,前端组件化开发提高了开发效率等等。面对快速发展的前端,我们应该去适应其带来的工作方式和流程的改变,目前的前后端分离的工作方式必然是今后的趋势所在,作为一个前端开发人员,我们应当承担这个普及前端新知识和改变现状的职责。相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!相关阅读:Angularjs如何实现mvvm式选项卡?案列+代码vue2.0的项目非常实用的代码集合
Vue,Django前后端分离,开发Openstack(五)Django,Vue前后端交互方法
@csrf_exempt 这个必须要有,否则跨域不了
编辑horizon/urls.py加入url
下一节内容:django调用openstack api(keystone)
Vue项目前后端分离下的前端鉴权方案
#?Vue项目前后端分离下的前端鉴权方案
###?技术栈
??前端Vue全家桶,后台.net。
###?需求分析
??1.?前端路由鉴权,屏蔽地址栏入侵
??2.?路由数据由后台管理,前端只按固定规则异步加载路由
??3.?权限控制精确到每一个按钮
??4.?自动更新token
??5.?同一个浏览器只能登录一个账号
###?前端方案
>?对于需求1、2、3,采用异步加载路由方案
??1.?首先编写vue全局路由守卫
??2.?排除登录路由和无需鉴权路由
??3.?登录后请求拉取用户菜单数据
??4.?在vuex里处理菜单和路由匹配数据
??5.?将在vuex里处理好的路由数据通过`addRoutes`异步推入路由
??```
????router.beforeEach((to,?from,?next)?=>?{
??????//?判断当前用户是否已拉取权限菜单
??????if?(store.state.sidebar.userRouter.length?===?0)?{
????????//?无菜单时拉取
????????getMenuRouter()
??????????.then(res?=>?{
????????????let?_menu?=?res.data.Data.ColumnDataList?||?[];
????????????//?if?(res.data.Data.ColumnDataList.length?>?0)?{
????????????//?整理菜单&路由数据
????????????store.commit("setMenuRouter",?_menu);
????????????//?推入权限路由列表
????????????router.addRoutes(store.state.sidebar.userRouter);
????????????next({...to,?replace:?true?});
????????????//?}
??????????})
??????????.catch(err?=>?{
????????????//?console.log(err);
????????????//?Message.error("服务器连接失败");
??????????});
??????}?else?{
????????//当有用户权限的时候,说明所有可访问路由已生成?如访问没权限的菜单会自动进入404页面
????????if?(to.path?==?"/login")?{
??????????next({
????????????name:?"index"
??????????});
????????}?else?{
??????????next();
????????}
??????}
????}?else?{
??????//?无登录状态时重定向至登录?或可进入无需登录状态路径
??????if?(to.path?==?"/login"?||?to.meta.auth?===?0)?{
????????next();
??????}?else?{
????????next({
??????????path:?"/login"
????????});
??????}
????}
??});
??```
??#####?注意
??>?我这里无需鉴权的路由直接写在router文件夹下的index.js,通过路由元信息meta携带指定标识
??```
????{
??????path:?"/err-404",
??????name:?"err404",
??????meta:?{
?????????authentication:?false
??????},
??????component:?resolve?=>?require(["../views/error/404.vue"],?resolve)
????},
??```
??>?上面说到路由是根据后台返回菜单数据根据一定规则生成,因此一些不是菜单,又需要登录状态的路由,我写在router文件夹下的router.js里,在上面步骤4里处理后台返回菜单数据时,和处理好的菜单路由数据合并一同通过`addRoutes`推入。?
??这样做会有一定的被地址栏入侵的风险,但是笔者这里大多是不太重要的路由,如果你要求咳咳,可以定一份字典来和后台接口配合精确加载每一个路由。
??```
??//?加入企业
??{
????path:?"/join-company",
????name:?"join-company",
????component:?resolve?=>?require([`@/views/index/join-company.vue`],?resolve)?
??},
??```
??>?在vuex中将分配的菜单数据转化为前端可用的路由数据,我是这样做的:
??管理系统在新增菜单时需要填写一个页面地址字段`Url`,前端得到后台菜单数据后根据`Url`字段来匹配路由加载的文件路径,每个菜单一个文件夹的好处是:你可以在这里拆分js、css和此菜单私有组件等
??```
??????menu.forEach(item?=>?{
????????????let?routerItem?=?{
??????????????path:?item.Url,
??????????????name:?item.Id,
??????????????meta:?{
????????????????auth:?item.Children,
??????????????},?//?路由元信息?定义路由时即可携带的参数,可用来管理每个路由的按钮操作权限
??????????????component:?resolve?=>
????????????????require([`@/views${item.Url}/index.vue`],?resolve)?//?路由映射真实视图路径
????????????};
????????????routerBox.push(routerItem);
????????});
??```
??>?关于如何精确控制每一个按钮我是这样做的,将按钮编码放在路由元信息里,在当前路由下匹配来控制页面上的按钮是否创建。
??菜单数据返回的都是多级结构,每个菜单下的子集就是当前菜单下的按钮权限码数组,我把每个菜单下的按钮放在此菜单的路由元信息`meta.auth`中。这样作的好处是:按钮权限校验只需匹配每个菜单路由元信息下的数据,这样校验池长度通常不会超过5个。
??```
??created()?{
????this.owner?=?this.$route.meta.auth.map(item?=>?item.Code);
??}
??methods:?{
??????matchingOwner(auth)?{
????????return?this.owner.some(item?=>?item?===?auth);
??????}
??}
??```
??>?需求4自动更新token,就是简单的时间判断,并在请求头添加字段来通知后台更新token并在头部返回,前端接受到带token的请求就直接更新token
??```
??//?在axios的请求拦截器中
??????let?token?=?getSession(auth_code);
??????if?(token)?config.headers.auth?=?token;
??????if?(tokenIsExpire(token))?{
????????//?判断是否需要刷新jwt
????????config.headers.refreshtoken?=?true;
??????}
??//?在axios的响应拦截器中
????if?(res.headers.auth)?{
??????setSession(auth_code,?res.headers.auth);
????}
??```
??>?对于需求5的处理比较麻烦,要跨tab页只能通过`cookie`或`local`,笔者这里不允许使用`cookie`因此采用的`localstorage`。通过打开的新页面读取`localstorage`内的`token`数据来同步多个页面的账号信息。`token`使用的`jwt`并前端md5加密。
??这里需要注意一点是页面切换要立即同步账号信息。
??>?经过需求5改造后的全局路由守卫是这样的:
??```
function?_AUTH_()?{
??//?切换窗口时校验账号是否发生变化
??window.addEventListener("visibilitychange",?function()?{
????let?Local_auth?=?getLocal(auth_code,?true);
????let?Session_auth?=?getSession(auth_code);
????if?(document.hidden?==?false?&&?Local_auth?&&?Local_auth?!=?Session_auth)?{
??????setSession(auth_code,?Local_auth,?true);
??????router.go(0)
????}
??})
??router.beforeEach((to,?from,?next)?=>?{
??????//?判断当前用户是否已拉取权限菜单
??????if?(store.state.sidebar.userRouter.length?===?0)?{
????????//?无菜单时拉取
????????getMenuRouter()
??????????.then(res?=>?{
????????????let?_menu?=?res.data.Data.ColumnDataList?||?[];
????????????//?if?(res.data.Data.ColumnDataList.length?>?0)?{
????????????//?整理菜单&路由数据
????????????store.commit("setMenuRouter",?_menu);
????????????//?推入权限路由列表
????????????router.addRoutes(store.state.sidebar.userRouter);
????????????next({...to,?replace:?true?});
????????????//?}
??????????})
??????????.catch(err?=>?{
????????????//?console.log(err);
????????????//?Message.error("服务器连接失败");
??????????});
??????}?else?{
????????//当有用户权限的时候,说明所有可访问路由已生成?如访问没权限的菜单会自动进入404页面
????????if?(to.path?==?"/login")?{
??????????next({
????????????name:?"index"
??????????});
????????}?else?{
??????????next();
????????}
??????}
????}?else?{
??????//?无登录状态时重定向至登录?或可进入无需登录状态路径
??????if?(to.path?==?"/login"?||?to.meta.auth?===?0)?{
????????next();
??????}?else?{
????????next({
??????????path:?"/login"
????????});
??????}
????}
??});
}
```
??>?经过需求5改造后的axios的请求拦截器是这样的,因为ie无法使用`visibilitychange`,并且尝试百度其他属性无效,因此在请求发出前做了粗暴处理:
??```
??if?(ie浏览器)?{?
??????setLocal('_ie',?Math.random())
??????let?Local_auth?=?getLocal(auth_code,?true);
??????let?Session_auth?=?getSession(auth_code);
??????if?(Local_auth?&&?Local_auth?!=?Session_auth)?{
????????setSession(auth_code,?Local_auth,?true);
????????router.go(0)
????????return?false
??????}
????}
??```
>?这里有一个小问题需要注意:因为用的`local`因此首次打开浏览器可能会有登录已过期的提示,这里相信大家都能找到适合自己的处理方案
??###??结语
经过这些简单又好用的处理,一个基本满足需求的前后端分离前端鉴权方案就诞生啦
如何进行前后端分离
对于前后端分离,认识上有个误区,那就是很多人自称:我们老早就分离了,全AJAX,使用Angular或者什么什么就可以了。
这个说法是不合适的,打个比方,别人问的是“如何解决家禽把蛋生在水草边的问题?”,但实际上人家养的是鸭子,答题的却是养鸡的,所以回答“不让去水边就行了”,这显然不在点子上。
这两年业界说的前后端分离,是限于偏展示类的系统(用A代替),而不是应用、管控类Web项目(用B代替),在B类项目里,前后端是天然分离的,对此,除了
少部分后端开发人员,基本所有人的认识都是一致的。上一段中这样回答的人一般都是只做B类项目,在B类项目里,前后端分离是共识,不需要讨论。
那么,剩下的问题就是讨论A类项目的前后端分离了。这个问题的核心在什么地方呢,在于模板的与数据结合的位置,以及,模板的控制权在谁手里。经过这两年的讨论,基本上我们可以达成的共识就是:模板应当由前端人员去控制,主要原因有两方面:
性能优化(尤其是外部资源的管理与发布,请求合并等等)
协作的顺畅性(已形成模板的界面片段的返工等问题)
那么,模板到底应该在什么地方跟数据结合?
这个问题就比较折腾了,有部分人尝试像B类项目那样,使用js模板,然后在浏览器端执行,这是存在一些问题的,比如说seo不友好,首屏性能不够,尤其对于首页DOM量很大的电商类网站,差距很明显。
所以我们还是得把主要的模板放在服务端来执行。在这个过程中,阿里作了一些尝试,那就是引入Node层,在这一层把模板与数据进行合成,然后浏览器拿到的就
是生成好的HTML了,但也不是所有HTML都是这么生成好的,还是会有一些内容等到了浏览器之后,再用js去加载和生成。
所以这一定会是一个混合方案,同一个系统中存在两种模板,一种在服务端执行,一种在浏览器中执行,互为补充。
至于说这个方案中,是否中间层一定要是node,我觉得无所谓,只要是能正常做web项目的东西都可以,这个还是要看所在企业的技术积累方向,当然node
做这块是有一些优势的,比如对前端人员的语言友好性,前后端模板的通用性等等,但这些都是细节,重点还是整体方案和流程。
这时候回头看你问题中的这句:
前后端分离的意思是,前后端只通过 JSON 来交流,组件化、工程化不需要依赖后端去实现。
我相信你这里对前后端的限定是以浏览器为准的,但事实上,A类项目中,前后端的分界一定要延伸到服务器端的模板层,也就是在这一层里,把各种来源的数据整合到模板中,这个数据未必是JSON格式的,会存在有JSON,XML,特定的二进制等等。
组件化这个话题就更复杂了,在刚才组织形式中,很难说出究竟什么才是组件。是某个商品的模板吗?是数据吗?是数据和模板的结合体吗?没法回答。在此,我说一句自己的看法:像电商这种项目的前端部分,基本不存在组件的概念,甚至不存在组件化的价值,因为这里面可复用的东西太少了,也不易提取,大多数东西都是不带逻辑的界面模板。
最近因为ReactJS的流行,带来了一个Isomorphic的概念,这是一种很有意义的探索,但是否能解决这类问题,尚不得而知,根据我的理解,它对B类项目是较好的补充方案,但对A类项目暂时还缺乏可用性,因为A类项目中,运行期的DOM变更并不多,多是整片的改变,用这个方案去解决的话,有些牛刀杀鸡的感觉。
对前后端分离设计模式的理解总结(部分Django描述)
FBV:Function base view 基于方法的视图
CBV:Class base view 基于类的视图
所以之后我了解到,其实是我没有了解 FBV 与 CBV 的概念。
正所谓:类就是 把数据封装进对象里 ,并赋予对象 行为 的能力。
所以我们完全可以把一个需求的接口封装成为一个类:
因为继承了 django 的 View 类,所以在默认情况下,会自动根据请求类型映射该类中对应的请求方法。
但是在所有的 python web 框架乃至一些其他语言的框架之中,对 HTTP 请求类型的方法映射都是由一个专门的反射函数来实现的 。
所以, 总结如下:
另外值得一提的是:自己那个类中的 dispatch 方法中如果不自己去映射而是调用父类(django 的 View)的 dispatch 方法,另外还在前后做一些附加操作,这样的功能跟 “ 装饰器 ” 就很相似了。
一共有10个项目,那让我们一起来慢慢学习吧!
300 系列:重定向类
400 系列 :客户端错误
500 系列: 服务端错误
如何解决Vue微信授权登录前后端分离的问题
这篇文章主要介绍了详解Vue微信授权登录前后端分离较为优雅的解决方案,内容挺不错的,现在分享给大家,也给大家做个参考。微信授权登录是一个非常常见的场景,利用微信授权登录,我们可以很容易获取用户的一些信息,通过用户对公众号的唯一openid从而建立数据库绑定用户身份.微信授权登录的机制这里不做详述,微信官方文档已有详述,简述就是通过跳转微信授权的页面,用户点击确认后,微信会跳到回调页面,此时回调页面url上会携带code参数,通过code参数,后端可以拿code换取拥护openid,或者用户信息在vue项目中,通常是一个SPA应用,即所有的页面都是同一个html,通常现在开发也是前后端彻底分离的,vue打包后生成的纯静态文件,甚至可以不经过服务器,所以通过后端弄跳转之类的都不太优雅,本文即介绍此类场景的微信授权登录对于一个vue的SPA应用,我们通常可能有很多页面,在微信公众号上我们可能配置多个菜单,多个菜单对应vue的路由页面,但是可能并不是每个页面都需要用户授权才能进入,有些页面用户不登录也需要可以预览,此时我们可以通过vue router来实现前端路由拦截 router.beforeEach(async (to, from, next) => { if (to.matched.some(recode => recode.meta.noAuth)) { next() } else { // store已存在用户信息直接进入页面 if (store.state.userInfo.nickname) { next() return } const code = getUrl(window.location.href).code // 截取url上的code ,可能没有,则返回''空字符串 let res = await api.post('/imsl/user/user-auth', [code]) // 获取用户信息,后端可首先通过cookie,session等判断,没有信息则通过code获取 console.log(res) // 返回用户信息 if (res.code === 200 && res.data.is_auth) { store.commit('setUserInfo', res.data) next() } else { // 此状态根据业务需求 可能不存在 if (res.code === 201) { const openid = res.data.openid console.log(openid) store.commit('setOpenid', openid) localStorage.setItem('openid', openid) next('/enlist-info') } // 上面的获取用户信息接口,如果cookie,session拿不到用户信息,且传递的code为空,则跳转到微信授权页面 if (res.code === 202) { console.log(window.location.origin) console.log(to.fullPath) // 这个redirectUrl用 当前页路径或者tof.fullPath(将要进入的路径) let redirectUrl = window.location.href redirectUrl = encodeURIComponent(redirectUrl) console.log(redirectUrl) const appid='wxdff0642c2120ea39' window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirectUrl}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect` } } }})上述代码基本阐述了一个授权的过程,首先,我们在配置vue路由的时候,设置此路由是否需要登录即给router的meta加一个noAuth:true的属性,这个是处理不需要登录的页面,通过router.beforeEach进行判断,如果是不需要登录的页面:noAuth,则直接next()让其进入相应页面.对于需要登录的页面,则让后端配合,此时,后端写一个获取用户信息的接口,前端则直接调用获取用户信息的接口,当然,不需要每个页面都调用,获取一次之后可以将用户信息存入vuex中,所以通过判断vuex里面有没有用户信息,如果已存在用户信息,则进入页面.没有用户信息那就调用后端获取用户信息的接口,说到这里,终于回到此文主题了,用户信息是通过微信授权登录拿到的,此时后端如何拿到用户信息呢?这里,可以跟后端商议好,用户绑定身份后,后端则可以通过设置cookie,token之类的保存这个用户登录状态,如果有相关状态,那么后端则可以直接返回用户信息. 如果是首次进入,或者cookie,token之类的已失效,那么此时则会调用微信授权登录了,如上述代码所述,分为三种情况,1. 通过cookie,token等,后端直接拿到了用户信息,此时则拿到用户信息直接进入页面,同时把用户信息存入vuex中2. 没有用户信息的情况,此时也没有cookie,token,那就需要重新调用微信授权登录了,上面给出的两种返回码code=201,code=202的情况,当code=2是则由前端直接跳转到微信授权页面,而redirectUri则为将要进入的页面,此时会发生什么呢?会跳到微信授权页面,用户点击之后又回到了这个页面,不同的是此时url上面已经携带了code,前端通过字符串截取拿到code,发送给后端,后端即可通过code换取openid以及用户信息了.总结:项目采用前后端完全分离方式,即打包后给的纯静态文件放在服务器,访问index.html后端不在接口处拦截,不需要后端跳转微信授权登录页面,由前端路由来拦截跳转,实现方法如3.前端在需要用户身份才能进入的页面通过vue-router的 router.beforeEach钩子函数拦截,此时调用获取用户信息接口,后端首先通过获取cookie,token等判断用户,无相关信息返回201或202,当返回202的时候,前端跳转到微信授权页,redirecturi即为要进入的页面的url,跳转授权后微信会在url上面携带code回到当前页,此时前端截取url上的code传给后端,后端通过code在后端处理拿到用户信息,openid等实现了授权登录