一 什么是重定向
重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其他位置。
二 为什么用重定向
举一个例子:
上面的例子意思就是,只要服务器发现用户没有登录,都会响应到登录页面,问题是当用户登录后我页面应该跳向何处?这里就要用到url重定向技术.
三 实现重定向
我们在发送请求的路径后面但是参数,因为添加参数后不会改变你请求的网页地址.
比如:你请求是本地5000端口下的login.html网页,现在你给这个网页地址带上参数id=123,这个新的url路径发给服务器后,服务器还是会返回login.html网页给浏览器,只不过服务器会拿到你带过去的参数.
// 没有带参数
127.0.0.1:5000/login.html
//带上参数
127.0.0.1:5000/login.html?id=123
所以,现在我们给所有要跳转到login.html的网页后面都带上一个参数,而这个参数就是当前网页的url地址.
比如:
3.1 从其他页面到登录页面
//1. 从商品页面跳转到登录页面
location.href = "login.html?redirectUrl=shop.html?id="+productID
//2. 从个人中心到登录页面
location.href = 'login.html?redirectUrl=user.html'
上面应该注意到的是从商品页面跳转到登录页面里面的redirectUrl(重定向url)的值是shop.html?id="+productID,这个路径里面又带有一个参数这并不会影响到时候重新跳向shop.html这个页面.
3.2 登录页面的响应
if(status = '登录成功') {
//页面跳回原来的页面
location.href = getQueryString('redirectUrl');
}else { //登录失败
// do something .....
}
//获取url中的参数值,name 是传入的参数值
function getQueryString (name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURI(r[2]);
return null;
}
总结: 重定向的实现只需要两步
给请求的网页路径后拼接一个参数redirectUrl,参数值就是当前网页的完整路径
在请求的网页里获取redirectUrl,再设置跳转的网页为redirectUrl的值
四 Vue里面的路由重定向
在Vue里面也有知识点与url重定向的一致,就是路由重定向.它定义了页面一开始就可以显示的内容.
语法:
下面的代码意思是,页面一来就显示goodlist的页面,利用了路由重定向的语法
const router = new VueRouter({
// (缩写) 相当于 routes: routes
routes: [
{ path: "/", redirect: "/goodlist" }, //路由重定向
{ path: "/goodlist", component: goodlist }, //设置goodlist路由规则
]
});
实例:
//router/index.js
//设置路由规则的文件夹
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
//1. 导入路由模板(模板也是组件)goodlist
import goodlist from "../components/goods/goodlist.vue";
import goodInfo from "../components/goods/goodInfo.vue";
//2. 设置路由规则
const router = new VueRouter({
// (缩写) 相当于 routes: routes
routes: [
{ path: "/", redirect: "/goodlist" }, //重定向
{ path: "/goodlist", component: goodlist }, //设置goodlist路由规则
{ path: "/goodInfo/:goodsId", component: goodInfo } //设置goodinfo路由规则
]
});
//导出路由规则
export default router;
五 Vue Router导航守卫
在vue同样涉及到从其他页面到登录页面,当登录成功后,又回到来到登录页面之前的页面.此时vue router里面的路由守卫就起到很大的作用.
这里面涉及到两个知识点:
5.1 导航守卫使用方法
你可以使用 router.beforeEach 注册一个全局前置守卫:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
每个守卫方法接收三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved。
5.1.1 实例
如果页面比较少,你可以一个一个判断页面的跳转
import Vue from 'vue';
import Router from 'vue-router';
import LoginPage from '@/pages/login'; //登陆页面
import HomePage from '@/pages/home'; //首页
import GoodsListPage from '@/pages/good-list'; //商品列表页
import GoodsDetailPage from '@/pages/good-detail'; //商品详情页
import CartPage from '@/pages/cart'; //购物车页面
import ProfilePage from '@/pages/profile'; //个人中心
//继承路由
Vue.use(Router)
//创建路由实例,并设置路由规则
const router = new Router({
routes: [
{
path: '/', // 默认进入路由
redirect: '/home' //重定向
},
{
path: '/login',
name: 'login',
component: LoginPage
},
{
path: '/home',
name: 'home',
component: HomePage
},
{
path: '/good-list',
name: 'good-list',
component: GoodsListPage
},
{
path: '/good-detail',
name: 'good-detail',
component: GoodsDetailPage
},
{
path: '/cart',
name: 'cart',
component: CartPage
},
{
path: '/profile',
name: 'profile',
component: ProfilePage
},
{
path: '**', // 错误路由
redirect: '/home' //重定向
},
]
});
// 全局路由守卫
router.beforeEach((to, from, next) => {
//from是来的页面,to是去的也页面,next是权限控制
if(to.path == "/profile" || to.path == "/cart") {
//进入购物车以及个人中心需要登陆校验
//发请求校验
const url = `site/account/islogin`
axios.get(url).then(res=>{
if(res.data.code == "logined") { //登录过
next() //有权限进入这个页面
}else {
//没登录打回到登录页
router.push({ name: "login" })
}
})
}else { //不需要登录校验的部分
next() //直接放过没进入这些页面
}
export default router;
但是如果页面很多需要一直用或运算来判断,那些网页需要验证,所以这时就可以用到路由元信息.
5.1.2 配合路由元信息使用
为什么会有路由元信息这个东西?
就是为了解决需要登录验证的网页太多的问题
meta字段(元数据)
直接在路由配置的时候,给每个路由添加一个自定义的meta对象,在meta对象中可以设置一些状态,来进行一些操作。用它来做登录校验再合适不过了.
//这样配置路由规则就可以了
{
name: "order",
path: "/order",
component: order,
meta: { checkoutLogin: true }
}
那上面的代码这样改进的就可以:
if(to.meta.checkoutLogin) { //需要登录校验的部分
//doSomething........
}
具体案例:
//设置路由规则的文件夹
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
//导入网络请求模块
import axios from 'axios';
//导入网站资源配置的模块
import global from "../config"
//设置默认基本的url,这是axios默认自带的
axios.defaults.baseURL= global.serverUrl
axios.defaults.withCredentials = true //让axios带上cookie
//暴露$axios到Vue的原型对象上全局变量上
Vue.prototype.$axios = axios
//1. 导入路由模板(模板也是组件)goodlist
import goodlist from "../components/goods/goodlist.vue";
import goodInfo from "../components/goods/goodInfo.vue";
import shopcart from "../components/shopcart/shopcart.vue";
import order from "../components/order/order.vue";
import login from "../components/login/login.vue"
//2. 设置路由规则
const router = new VueRouter({
// (缩写) 相当于 routes: routes
routes: [
{ path: "/", redirect: "/goodlist" }, //重定向
{ name: "GOODLIST", path: "/goodlist", component: goodlist }, //设置goodlist路由规则
{ path: "/goodInfo/:goodsId", component: goodInfo }, //设置goodinfo路由规则
{ path: "/shopcart", component: shopcart }, //设置shopcart路由规则
{ name: "login", path: "/login", component: login}, //设置登录页的路由规则
/************需要登录验证的部分 *******************/
{ name: "order", path: "/order", component: order, meta: { checkoutLogin: true } } //设置order路由规则,这里是params传值
]
});
//3.利用导航守卫做登录验证
router.beforeEach((to, from, next) => {
//from是来的页面,to是去的也页面,next是权限控制
if(to.path != "/login") {
//如果不是登录请求页面,那么记录来的路径方便以后使用
localStorage.setItem('wantVisitPath',to.fullPath)
}
if(to.meta.checkoutLogin) { //需要登录校验的部分
//发请求校验
const url = `site/account/islogin`
axios.get(url).then(res=>{
if(res.data.code == "logined") { //登录过
next()
}else {
//没登录打回到登录页
// router.push({ path : "/login" })
router.push({ name: "login" })
}
})
}else { //不需要登录校验的部分
next()
}
})
//导出路由规则
export default router;