微信小程序之页面拦截器的示例代码


Posted in Javascript onSeptember 07, 2017

场景

  • 小程序有52个页面,其中13个页面无需任何身份,另外39个页面需要系统角色。对于这39个页面,如果微信用户没有系统角色,则跳转到登录页。
  • 是否有系统角色信息需要通过异步请求来获取。

需求分析&实现

对需求进行抽象,其实要的就是一个过滤器,对小程序页面的访问进行过滤,符合条件的通过,不符合条件进行其他处理。

使用过php的laravel框架的童鞋,肯定一下子就联想到了laravel框架的http中间件:

HTTP 中间件提供一个方便的机制来过滤进入应用程序的 HTTP 请求,例如,Laravel 默认包含了一个中间件来检验用户身份验证,如果用户没有经过身份验证,中间件会将用户导向登录页面,然而,如果用户通过身份验证,中间件将会允许这个请求进一步继续前进。当然,除了身份验证之外,中间件也可以被用来执行各式各样的任务,CORS 中间件负责替所有即将离开程序的响应加入适当的响应头,一个日志中间件可以记录所有传入应用程序的请求。

令人忧桑的是,微信小程序并没有提供针对Page实例的中间件机制。所以只能从Page实例的生命周期处下手。

微信小程序之页面拦截器的示例代码

对于onLoad,一个页面只会调用一次;对于onShow,每次打开页面(比如小程序从后台转到前台)都会调用一次。

在onLoad或者onShow钩子函数里,对用户身份进行校验,通过后则拉取该页面需要的数据,否则跳转到登录页。

//orderDetail.js
onShow: function () {
  let that = this;
  //身份校验
  service.identityCheck(() => {
     //跳转到登录页
     wx.redirectTo({
      url: "/pages/common/login/login"
     });
    }, () => {  
     //获取页面数据等等   
     that.getDetail(this.orderId);
     ...
    }
  );
 },

不过,每个页面都要这样写,重复代码好多啊,侵入性也强。不如用装饰函数(高大上的说法是装饰者模式)来包装一下:

//filter.js
function identityFilter(pageObj){
  if(pageObj.onShow){
    let _onShow = pageObj.onShow;
    pageObj.onShow = function(){
      service.identityCheck(()=>{
        //跳转到登录页
        wx.redirectTo({
          url: "/pages/common/login/login"
        });
      },()=>{
        //获取页面实例,防止this劫持
        let currentInstance = getPageInstance();
        _onShow.call(currentInstance);
      });
    }
  }
  return pageObj;
}

function getPageInstance(){
  var pages = getCurrentPages();
  return pages[pages.length - 1];
}

exports.identityFilter = identityFilter;

filter.js用以提供过滤器方法,除了现有的用户身份拦截,后续如果需要其他拦截,可以在这个文件增加。然后,在需要用户身份拦截的小程序页面代码里,用filter.identityFilter处理一下就可以了:

//orderDetail.js
let filter = require('filter.js');
Page(filter.identityFilter({
  ...
  onShow: function () {
    //获取页面数据等等
    this.getDetail(this.orderId);
    //...
  },
  ...
}));

使用Promise进行优化

上面的实现中,每次访问页面,都会执行一次获取用户身份的方法(就是上面代码里的service. identityCheck )。其实没有必要,在小程序启动的时候获取一次就行了。也就是说,放在app.js的onLaunch方法里执行。

每个小程序页面实例化时,一般也会执行异步方法,用来获取页面需要的数据。关键在于,我们需要保证,页面的异步方法 必须在 获取用户身份的异步请求 之后执行。

毋容置疑,Promise最擅长处理异步请求的执行顺序了。主子,快放代码粗来:

//app.js
App({
  onLaunch:function(){
    let p = new Promise(function(resolve,reject){
      service.identityCheck(resolve,reject);
    });
    this.globalData.promise = p; 
  },
  ...
  globalData: {
    promise:null,
  }  
});
//filter.js
const appData = getApp().globalData;
function identityFilter(pageObj){
  if(pageObj.onShow){
    let _onShow = pageObj.onShow;
    pageObj.onShow = function(){
      //改动点
      appData.promise.then(()=>{
        //跳转到登录页
        wx.redirectTo({
          url: "/pages/common/login/login"
        });
      },()=>{
        //获取页面实例,防止this劫持
        let currentInstance = getPageInstance();
        _onShow.call(currentInstance);
      });
    }
  }
  return pageObj;
}

小结

基本实现了小程序页面的用户身份拦截器,但是比起laravel的http中间件还是逊色一些:

  • 需要对每个页面代码包装一层。
  • 即使用户身份校验不通过,小程序也并不会阻塞页面的渲染。假如获取用户身份的异步方法一分钟才执行完,小程序页面还是会展示出来,一分钟之后才跳转到登录页。需要自己增加逻辑,比如在这一分钟内,页面展示空白内容。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
指定js可访问其它域名的cookie的方法
Sep 18 Javascript
很酷的javascript loading效果代码
Jun 18 Javascript
JavaScript 字符串与数组转换函数[不用split与join]
Dec 13 Javascript
预加载css或javascript的js代码
Apr 23 Javascript
Dojo 学习要点
Sep 03 Javascript
基于JQuery 选择器使用说明介绍
Apr 18 Javascript
jQuery Animation实现CSS3动画示例介绍
Aug 14 Javascript
jQuery带进度条全屏图片轮播特效代码分享
Jun 28 Javascript
js图片跟随鼠标移动代码
Nov 26 Javascript
Vue2实现组件props双向绑定
Dec 02 Javascript
浅析Node.js非对称加密方法
Jan 29 Javascript
小程序选项卡以及swiper套用(跨页面)
Jun 19 Javascript
基于js粘贴事件paste简单解析以及遇到的坑
Sep 07 #Javascript
微信小程序实现轮播图效果
Sep 07 #Javascript
使用mint-ui开发项目的一些心得(分享)
Sep 07 #Javascript
JavaScript+CSS相册特效实例代码
Sep 07 #Javascript
AngularJS 打开新的标签页实现代码
Sep 07 #Javascript
基于Cookie常用操作以及属性介绍
Sep 07 #Javascript
基于require.js的使用(实例讲解)
Sep 07 #Javascript
You might like
PHP+JS无限级可伸缩菜单详解(简单易懂)
2007/01/02 PHP
PHP实现定时执行任务的方法
2014/10/05 PHP
WordPress主题制作中自定义头部的相关PHP函数解析
2016/01/08 PHP
PHP类的声明与实例化及构造方法与析构方法详解
2016/01/26 PHP
在线游戏大家来找茬II
2006/09/30 Javascript
JS 面向对象的5钟写法
2009/07/31 Javascript
jquery select选中的一个小问题
2009/10/11 Javascript
JavaScript图片放大技术(放大镜)实现代码分享
2013/11/14 Javascript
JS实现文字向下滚动完整实例
2015/02/06 Javascript
jQuery中animate用法实例分析
2015/03/09 Javascript
Angularjs 实现分页功能及示例代码
2016/09/14 Javascript
js导出excel文件的简洁方法(推荐)
2016/11/02 Javascript
bootstrap table 表格中增加下拉菜单末行出现滚动条的快速解决方法
2017/01/05 Javascript
vue Render中slots的使用的实例代码
2017/07/19 Javascript
jQuery上传插件webupload使用方法
2017/08/01 jQuery
JS实现的ajax和同源策略(实例讲解)
2017/12/01 Javascript
一些可能会用到的Node.js面试题
2019/06/15 Javascript
Vue配置marked链接添加target="_blank"的方法
2019/07/19 Javascript
详解element-ui中el-select的默认选择项问题
2019/08/02 Javascript
node express使用HTML模板的方法示例
2019/08/22 Javascript
vue + el-form 实现的多层循环表单验证
2020/11/25 Vue.js
[01:16:50]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第一场 3月7日
2021/03/11 DOTA
Python 文件处理注意事项总结
2017/04/10 Python
Python实现生成随机日期字符串的方法示例
2017/12/25 Python
python批量导入数据进Elasticsearch的实例
2018/05/30 Python
python+opencv打开摄像头,保存视频、拍照功能的实现方法
2019/01/08 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
2019/06/13 Python
django的ORM操作 删除和编辑实现详解
2019/07/24 Python
numpy.transpose()实现数组的转置例子
2019/12/02 Python
Python实现微信表情包炸群功能
2021/01/28 Python
阿里旅行:飞猪
2017/01/05 全球购物
有趣的睡衣和礼物:LazyOne
2019/11/27 全球购物
劳动竞赛活动总结
2014/05/05 职场文书
农村房屋租赁合同(范本)
2019/07/23 职场文书
MySQL索引篇之千万级数据实战测试
2021/04/05 MySQL
教你一步步实现一个简易promise
2021/11/02 Javascript