封装微信小程序http拦截器

13908708-f8d8a5d77bdca7bb.png
微信小程序

微信小程序是数据驱动的应用,开发技术和vue、react和angular等mv*技术类似。在vue下可以用vue-resource、axios等模块进行http请求,但是在微信小程序上,http请求只支持wx.request(OBJECT),所以我们需要对wx.request进行封装,实现http拦截器的功能。


第一步:创建一个request.js文件


第二步:确定http、upload和websocket前缀

13908708-ae049bb4dfc69c48.png
require.js  填写请求前缀


第三步:封装wx.request

13908708-b7467b53c17488ac.png
request.js  function fun

        在请求发出前处理http地址、请求头和参数、在响应后解析返回值并做基本的逻辑判断,重点是使用Promise对象。


第四步:导出模块

13908708-f93ef94096bbdc7a.png
request.js  导出模块



第五步:使用request

const Request = require("/utils/request");//导入模块

Request.post("/api/xcxWxLogin", {  //调用方法

              code: res.code,

              encryptedData: resp.encryptedData,

              iv: resp.iv,

              shareId: share.shareId || "",

              salesmanId: share.salesmanId || "",

              source: share.source || ""

}).then(res => { //成功回调

        //todo

}).catch(err => {}); //异常回调


第六步:拦截器完整代码

const apiHttp = "https://*****.com";

const socketHttp = "wss://*****.com/wss";

function fun(url, method, data, header) {

  data = data || {};

  header = header || {};

  let sessionId = wx.getStorageSync("UserSessionId");

  if (sessionId) {

    if (!header || !header["SESSIONID"]) {

      header["SESSIONID"] = sessionId;

    }

  }

  wx.showNavigationBarLoading();

  let promise = new Promise(function(resolve, reject) {

    wx.request({

      url: apiHttp + url,

      header: header,

      data: data,

      method: method,

      success: function(res) {

        if (typeof res.data === "object") {

          if (res.data.status) {

            if (res.data.status === -200) {

              wx.showToast({

                title: "为确保能向您提供最准确的服务,请退出应用重新授权",

                icon: "none"

              });

              reject("请重新登录");

            } else if (res.data.status === -201) {

              wx.showToast({

                title: res.data.msg,

                icon: "none"

              });

              setTimeout(function() {

                wx.navigateTo({

                  url: "/pages/user/supplement/supplement"

                });

              }, 1000);

              reject(res.data.msg);

            }

          }

        }

        resolve(res);

      },

      fail: reject,

      complete: function() {

        wx.hideNavigationBarLoading();

      }

    });

  });

  return promise;

}

function upload(url, name, filePath) {

  let header = {};

  let sessionId = wx.getStorageSync("UserSessionId"); //从缓存中拿该信息

  if (sessionId) {

    if (!header || !header["SESSIONID"]) {

      header["SESSIONID"] = sessionId; //添加到请求头中

    }

  }

  wx.showNavigationBarLoading();

  let promise = new Promise(function(resolve, reject) {

    wx.uploadFile({

      url: apiHttp + url,

      filePath: filePath,

      name: name,

      header: header,

      success: function(res) {

        resolve(res);

      },

      fail: reject,

      complete: function() {

        wx.hideNavigationBarLoading();

      }

    });

  });

  return promise;

}

module.exports = {

  apiHttp: apiHttp,

  socketHttp: socketHttp,

  "get": function(url, data, header) {

    return fun(url, "GET", data, header);

  },

  "post": function(url, data, header) {

    return fun(url, "POST", data, header);

  },

  upload: function(url, name, filePath) {

    return upload(url, name, filePath);

  }

};

### 微信小程序页面拦截器方法 #### 使用场景与需求分析 在开发微信小程序过程中,有时需要对用户的访问行为进行控制,比如验证用户身份或权限。通过实现页面拦截机制,在特定条件下阻止用户进入某些页面或将用户重定向至其他页面。 #### 方案一:利用页面加载事件`onLoad()`和显示事件`onShow()` 可以在每个页面的 `onLoad()` 或者更推荐的是 `onShow()` 生命周期函数里加入逻辑判断来决定是否允许展示当前页面的内容。如果检测到未满足条件(如缺少必要的认证信息),则可以执行跳转操作[^1]: ```javascript Page({ data: {}, onLoad(options){ // 此处可做一些初始化工作 }, onShow(){ const app = getApp(); if (!app.globalData.hasLogin){ // 假设全局变量中有登录状态标记 wx.redirectTo({url:'/pages/login/index'}); // 如果没登录,则转向登录界面 } } }) ``` 这种方法简单易懂,适用于小型项目中的基本权限管理;但对于大型应用来说可能会显得冗余,因为几乎所有的页面都需要重复相同的代码片段来进行同样的检查。 #### 方案二:创建中间件/工具类统一处理 为了提高代码复用性和维护效率,建议构建一个通用的方法用于所有页面之前的一致性校验。可以通过编写公共模块的方式完成这一目标。下面是一个简单的例子说明如何使用自定义库文件来简化这个过程[^3]: 首先建立名为`authInterceptor.js`的新脚本文件: ```javascript // authInterceptor.js const checkAuth = (toUrl)=>{ let pages=getCurrentPages(); let currentPage=pages[pages.length-1]; let options={...currentPage.options}; const app = getApp(); if(!app.globalData.hasLogin && !['login'].includes(currentPage.route.split('/')[1])){ wx.reLaunch({url:`/pages/login/index?redirect=${encodeURIComponent(toUrl)}`}); return false; } return true; } module.exports={ checkAuth } ``` 接着修改各个页面的入口配置如下所示: ```javascript import {checkAuth} from '../../common/authInterceptor' Page({ onLoad:function(option){ var that=this; if(checkAuth(that.route)){ // 继续原有业务逻辑... } }, ... }) ``` 此方案不仅减少了不必要的代码复制粘贴现象,还使得整个项目的结构更加清晰合理。同时也可以很容易地扩展更多的功能特性,例如记录日志、统计流量等。 #### 方案三:基于请求封装实现API级别的拦截 对于涉及网络通信的操作而言,除了上述两种方式外还可以考虑直接针对HTTP请求本身实施过滤措施。借助于第三方框架提供的能力或是自行设计一套轻量级解决方案都可以达到目的。以下是采用Promise风格编写的简易版axios-like API客户端实例[^4]: 先安装依赖项(如果有): ```bash npm install axios --save-dev ``` 随后编辑`request.js`: ```javascript // request.js import axios from 'axios'; function createRequestInstance(config={}){ const instance = axios.create({...config}); // 请求前置处理器 instance.interceptors.request.use( config => { const token=wx.getStorageSync('token'); if(token){ config.headers.Authorization=`Bearer ${token}`; } return config; }, error=> Promise.reject(error) ); // 响应后置处理器 instance.interceptors.response.use( response=>{ const status=response.status; switch(status){ case 200: break; default : throw new Error(`Unexpected HTTP Status Code:${status}`); } return response.data; }, error=>{ if(error.response&&error.response.status===401){ wx.navigateTo({url:'/pages/login/index'}); } return Promise.reject(error); } ) return instance; } export const fetchData=(endpoint,params={},method='GET',successCallback,failureCallback)=> { try{ const client=createRequestInstance(); client({url:endpoint,data:params,method}).then(successCallback).catch(failureCallback); } catch(e){ failureCallback(e.message||e.toString()); } }; ``` 最后调整调用位置的相关部分为: ```javascript import {fetchData} from './path/to/request'; ... fetchData('/api/someEndpoint',{paramName:'value'},'POST', res=>console.log(res), err=>console.error(err)); ``` 这种方式的优势在于它能够有效地分离关注点——即把鉴权相关的细节隐藏起来不让前端开发者操心太多的同时也保证了安全性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值