美文网首页
小程序request的封装

小程序request的封装

作者: 雨田君的记事本 | 来源:发表于2018-10-30 16:19 被阅读0次

    wx.request 的封装

    小程序提供了request的网络接口,用于服务器交互。但是我们在开发的过程中发现了以下问题:

    • 每个页面中都要去写一些重复的相关配置,比如header
    • 没有统一的loading提示管理
    • 没有统一的错误处理机制
    • 页面逻辑与请求服务器代码混在一起,比较混乱,不好调试

    统一header问题

    发起请求时,服务器有些接口需要验证用户身份,一般是会把用户登录之后的token设置在header中,回传给服务器,我们可以写一个通用的方法:

    /**
     * 获取header
     */
    function getCommonHeader() {
    
      let header = {
        'Content-type': 'application/x-www-form-urlencoded'
      };
    
      // 如果token有值则带上
      let token = wx.getStorageSync("token");
      if (token) {
        header = Object.assign({}, header, {
          'Authorization': 'Bearer ' + token
        });
      }
    
      return header;
    };
    

    统一loading管理

    为了防止用户多次点击以及更好的用户体验,一般发起请求时会加上loading动画,服务器返回之后再去掉这个loading。但是产品设计时也有不加loading动画和自定义loading文字的需求,所以我们可以添加一个控制开关 showLoadingloadingTitle ,由外部调用时设置。

    统一错误处理机制

    这里需要和服务器约定统一返回结果格式,比如:

    {"code": 0, "data": "", "msg": "ok"}
    

    解释一下:

    • code 表示本次请求的状态码
    • data 是服务器返回的数据
    • msg 业务错误提示

    首先对此次请求的http状态判断,非 200 则表示此次请求失败了,可能是 500 服务器报错,也可能是 404 请求服务器url未找到等等。
    接着对业务状态判断,这个由服务器约定,比如 0 表示成功,非 0 则表示业务错误,一般直接 toast 提示服务器返回的 msg 就可以了,这样就对服务器错误进行了统一处理。
    但是和 loading 一样,有些页面需要有特殊的错误处理,这时我们也添加一个控制开关 showToast ,由调用时控制是否显示统一的错误信息。

    接口promise化

    为了调用时少些回调,我们把这个request接口包装成一个promise,调用时直接使用 thencatch 来处理业务。最终的代码如下:

    
    /**
     * 网络请求
     */
    function request(url, data = {}, header = {}, method = "POST", config = {}) {
    
      // header 空值处理
      let _header = {
        "content-type": "application/x-www-form-urlencoded"
      };
      if (Object.keys(header).length > 0) {
        _header = header;
      }
    
      let showToast = true,
        showLoading = false,
        loadingTitle = "加载中。。。";
      // 默认显示toast
      if (config['showToast'] != undefined && config['showToast'] == false) {
        showToast = false;
      }
      // 默认显示loading
      if (config['showLoading'] != undefined && config['showLoading'] == true) {
        showLoading = true;
      }
      if (config['loadingTitle']) {
        loadingTitle = config['loadingTitle'];
      }
    
      return new Promise((resolve, reject) => {
        // 是否显示loading
        if (showLoading) {
          wx.showLoading({ title: loadingTitle, icon: 'none', mask: true });
        }
    
        wx.request({
          url: url,
          data: data,
          header: _header,
          method: method,
          success: (res => {
            if (showLoading) {
              wx.hideLoading();
            }
    
            // 服务器 非200 错误
            if (res.statusCode && res.statusCode != 200) {
              wx.showToast({ title: '服务器 ' + res.statusCode + ' 错误', icon: 'none' });
              reject(res);
              return;
            }
    
            if (res.data && res.data.code != 0) {
              // 业务状态非0 是否提示
              if (showToast) {
                wx.showToast({ title: res.data.msg, icon: 'none' });
              }
    
              reject(res);
              return;
            }
            resolve(res.data);
          }),
          fail: (err => {
            if (showLoading) {
              wx.hideLoading();
            }
    
            if (err.errMsg.indexOf('url not in domain list') > -1) {
              wx.showToast({ title: '请求url不在合法域名中,请打开调试模式', icon: 'none' });
            }
    
            reject(err);
          })
        });
      });
    
    };
    
    

    对于 get 请求和 post 请求我们再包装一下

    
    /**
     * get 网络请求
     */
    function getRequest(url, data = {}, header = {}, config = {}){
      return request(url, data, "GET", header, config);
    }
    
    /**
     * post 网络请求
     */
    function postRequest(url, data = {}, header = {}, config = {}){
      return request(url, data, "POST", header, config);
    }
    

    我们看看调用的例子,将上面封装好的request函数放到 utils.js里面,新建一个api.js文件:

    const utils = require('../utils.js');
    
    module.exports = {
      getUserInfo: function(data, config = {}){
        return utils.postRequest(
          'http://api.xx.com/get_user_info',
          data,
          utils.getCommonHeaders(),
          config
        );
      }
    }
    

    然后页面调用:

    const api = require('../api.js');
    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
      api.getUserInfo({
          "user_id": "1"
        }, {
          "showLoading": "false",
          "showToast": "false",
          "loadingTitle": "登录中"
        })
        .then(res => {
          console.log(res);
        });
    }
    

    一般情况下上面的 showLoading 参数等配置项可以不写,用默认就行,那页面就更简洁了

    const api = require('../api.js');
    
    api.getUserInfo({"user_id": "1"})
      .then(res => {
        console.log(res);
      });
    

    相关文章

      网友评论

          本文标题:小程序request的封装

          本文链接:https://www.haomeiwen.com/subject/sirxaftx.html