微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

小程序如何实现网络请求 详细过程

本篇文章给大家带来的内容是关于小程序如何实现网络请求 (详细过程),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

对于小程序而言,网络请求封装的要比Android强大多了,这一点值得赞扬。官方示例:

wx.request({
  url: 'test.PHP', //仅为示例,并非真实的接口地址
  data: {
     x: '' ,
     y: ''
  },  header: {    'content-type': 'application/json' // 认值
  },
  success: function(res) {
    console.log(res.data)
  }
})

but…but…这调用起来貌似很简单,但是,似乎有点不对劲?哪儿不对劲呢——每次调用代码太多了。而且,对于网络请求的日志文件不好管理。这离我们最理想的方式还是有点差距的。
那么,我们最理想的方式是希望是怎么样的呢?

1、代码简洁,一行代码去搞定。
2、对于常用的字段统一封装管理。如 token、版本号version等
3、自定义异常处理。如未登录时,不用每写一个接口都去判断是否登录注册

 api.request1(data, function (result) { //数据请求成功,
  },   function(error){//失败
 })

那么,基于上面的问题。我来一步步进行剖析。

一、网络请求的场景分析

1、支持token传入的网络请求。

这种情况比较少见的。我现在的项目中就遇到了。大概意思是管理员可以操作旗下的其他的虚拟用户管理员登录生成一个token,每生成一个成员时,会生成一个虚拟的virtualToekn,以后每次管理员操作这个成员时,都需要用这个virtualToken,但是管理员获取自己的信息时,还是需要用自己的token。这个时候就要支持自定义的token传入了。

2、网络请求的劫持。

这种场景主要有两种情况:

1、如果网络失败
2、没有token时,这种场景主要出现在登录后置中。如商城类app查看购物车等

解决方法:直接返回失败,在发起网络请求前结束本次网络请求操作,减少预知的错误网络访问

3、支持自定义loading窗的弹出和隐藏控制

1、loading窗的弹出:这种场景比较多,如下拉刷新列表时,是不需要loading窗出现的。但是获取用户信息是需要loading出现的
2、loading窗的隐藏:这种场景是如果调用一个接口成功后,然后要连续调用第二个接口。这样在第一次接口成功后,不应该让loading窗消失,而是最后一次接口结束后才隐藏。

4、对网络不同的错误,进行处理

二、代码分析

/**
 * 自定义token  请求
 * 
 * isShowLoading :true  弹出loading窗
 * isEndLoading: true  最后需要隐藏loading窗。若是false,则不隐藏
 * token: 可以自定义token。用户虚拟账号使用车辆
 */
 export function requestApi(requestData, isShowLoading = true,isEndLoading = true, token = null,onSuccess, onFail) {  
 let app = getApp().globalData;  // 1、检查是否已经登录,在未登录的时候,可以提前缓存一个临时token欺骗本次检查。等登录完成后,再更新token值
  if (!util.hasLogin()) {    return;
  }  // 2、检查网络状态
  if (!util.checkNetworkConnected()) { //没有网络
    onFail(网络请求失败,稍后再试)    return;
  }  if (!requestData) {
    onFail(数据异常,请稍后再试)    return;
  }  let cachetoken =  util.taketoken()  let newToken = token == null ? cachetoken : token
  console.log(newToken===========>, newToken)
  requestData.token = newToken
  requestData.version = app.version
  console.log(==================================================开始请求网络数据start========================================)
  console.log(requestData)
  console.log(==================================================开始请求网络数据end===========================================)  var baseUrl = app.debug ? app.debugUrl : app.releaseUrl    
  console.log(===baseUrl===> + baseUrl)  if (isShowLoading){
    util.showLoading(加载中)
  }
  const requestTask = wx.request({
    url: baseUrl,    data: requestData,    header: {      'content-type': 'application/json'
    },
    method: 'POST',
    dataType: 'json',
    success: function(res) {
      console.log(==================================================返回请求结果start========================================)
      console.log(res.data)
      console.log(==================================================返回请求结果end===========================================)      
      if (res.data.code == 0) { //成功
        // console.log(onSuccess===========>, onSuccess);
        onSuccess(res.data)
      } else if (res.data.code == 1021) { //未缴纳押金
        wx.navigateto({
          url: '/pages/recharge/recharge',
        })        return false;
      } else if (res.data.code == 1006) { //余额不足
        wx.navigateto({
          url: '/pages/deposited/deposited',
        })        return false;
      } else if (res.data.code == 1019) { //未实名
        wx.navigateto({
          url: '/pages/certify/certify',
        })        return false;
      } else if (res.data.code == 1001) { //token过期
        wx.relaunch({
          url: '/pages/login/login'
        });        return false;
      } else { //失败
        let error = res.data == null || typeof (res.data) == undefined ? 网络请求失败,请稍后再试 : res.data.desc
        onFail(error)
        console.log(error===========>, error);
      }
    },
    fail: function(res) {
      console.log(onFail===========>, res);
      onFail(网络请求失败,稍后再试)
    },
    complete: function(res) {
      console.log(complete===========>, isEndLoading);      
      if (isEndLoading){
        wx.hideLoading()
      }
    }
  })
};

三、网络环境统一切换。

在app.json中统一配置

  // 全局的数据,可以提供给所有的page页面使用
  globalData: {
    token: ,
    version: version版本号,
    releaseUrl: 正式版url,
    debugUrl: 测试版url,    debug: true   //true  debug环境,false正式环境
  },

这样,以后切换网络环境只需要修改debug值即可。

四、二次封装

/**
 * 自定义loading  框请求
 * 
 * isShowLoading :true  弹出loading窗
 * isEndLoading: true  最后需要隐藏loading窗。若是false,则不隐藏
 */
 export function request(requestData, isShowLoading = true, isEndLoading = true, onSuccess, onFail){  
 this.requestApi(requestData, isShowLoading, isEndLoading, null, function (result) {
    onSuccess(result)
  }, function (error) {
    onFail(error)
  })
}/**
 *  带有loading 框的 不能自定义的请求
 * 
 */export function request1(requestData, onSuccess, onFail) {  // console.log(onSuccess========request1===>, success, fail);
  requestApi(requestData, true, true, null, function (result) {
    onSuccess(result)
  }, function (error) {
    onFail(error)
  })
}/**
 * 自定义token  请求
 * 
 * isShowLoading :true  弹出loading窗
 * isEndLoading: true  最后需要隐藏loading窗。若是false,则不隐藏
 * token: 可以自定义token。用户虚拟账号使用车辆
 */export function request2(requestData, isShowLoading = true, isEndLoading = true, token = null, onSuccess, onFail) {
  requestApi(requestData, isShowLoading, isEndLoading, token, function (result) {
    onSuccess(result)
  }, function (error) {
    onFail(error)
  })
}/**
 * 自定义loading  框请求
 * 
 * isShowLoading :true  弹出loading窗
 * isEndLoading: true  最后需要隐藏loading窗。若是false,则不隐藏
 */export function request3(requestData, isShowLoading = true, isEndLoading = true, token, onSuccess, onFail) {
  requestApi(requestData, isShowLoading, isEndLoading, token, function (result) {
    onSuccess(result)
  }, function (error) {
    onFail(error)
  })
}

end

最后,控制台查看日志的示意图为:

20180915143125445.png

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


开发微信小程序的用户授权登录功能
小程序开发页面如何实现跳转?
浅谈小程序开发中蓝牙连接错误分析及解决方法
什么是小程序?它有哪些功能?
如何配置小程序开发项目结构?(教程)
怎么把自己的店加入小程序
微信小程序怎么实现购物车功能?(方法介绍)
小程序使用函数节流解决页面多次跳转问题
小程序中下拉刷新页面的功能怎么实现?
小程序生成参数二维码的方法介绍