首頁 >微信小程式 >小程式開發 >小程式如何實現網路請求 (詳細過程)

小程式如何實現網路請求 (詳細過程)

不言
不言原創
2018-09-18 16:24:193804瀏覽

這篇文章帶給大家的內容是關於小程式如何實現網路請求 (詳細過程),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

對於小程式而言,網路請求封裝的要比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

最後,控制台檢視日誌的示意圖為:
小程式如何實現網路請求 (詳細過程)

以上是小程式如何實現網路請求 (詳細過程)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn