微信小程序 - 请求API自动携带token

3,121 阅读2分钟

微信小程序原生的网络请求we.request,存在以下几个问题

当发生多层网络请求嵌套时,代码结构很差,需要改写成promise形式

有的接口需要用户登录,即携带token(用户登录成功后,后台返回的token,存储在小程序中)才能进行访问,否则会返回认证失败,所以要解决2个问题,1是自动携带token,2是认证失败最好重新登录重新进行访问

网络请求经常用到,现在的写法很多都是重复的

所以我们必须对网络请求进行封装。

封装的请求流程大致如下

检查是否有网络,无网络提醒稍候重试

如果有网络发起请求,请求时携带token到header的Authorization中

如果返回数据code==1001(认证失败的错误码,根据自己情况改写),则重新进行登录操作

a. 调用wx.login获取code

b.调用后台的login接口,登录成功返回token

c.将token存储到本地

d.再次发起网络请求

如果返回数据code==1(成功),调用成功回调

其他情况 调用失败回调

源码如下,其中所有的小程序接口均已改成promise形式,见 shanhuxueyuan.com/news/detail…

//network.js

var wxapi = require("../network/base.js").wxapi; var api=require("../network/config.js").api;

const method={ post: "POST", get: "GET" }

function fetch({ url, data = '', method='POST'}){ return new Promise((resole,reject)=>{ wxapi("getNetworkType") .then(res=>{ if (res.networkType=="none"){ wx.showToast({ title: '网络好像不太好哦,请稍候再试', icon: "none" }) }else{ wxapi("request", { url: api.base_url + url, header: { 'Authorization': 'Bearer ' + wx.getStorageSync('token'), 'content-type': 'application/x-www-form-urlencoded' // 默认值 }, data: data, method: method, }) .then(res => { if (res.data.code == 1001) { //认证失败,重新登录 wx.showToast({ title: '验证失败,自动重试', icon:"none"

          })
          wxapi("removeStorage", { key: "token" })
            .then(() => wxapi("login"))
            .then(res => fetch({
              url: api.login,
              data: {
                code: res.code
              },
            })
            )
            .then(res => {
              if (res.code == 1) {
                //登录成功,重新请求一次
                wx.setStorageSync('token', res.data.token)
                wxapi("request", {
                  url: api.base_url + url,
                  header: {
                    'Authorization': 'Bearer ' + wx.getStorageSync('token'),
                    'content-type': 'application/x-www-form-urlencoded' // 默认值
                  },
                  data: data,
                  method: 'POST',
                })
                  .then(res => {
                    if (res.data.code == 1) {
                      resole(res.data)
                    } else {
                      reject(res.data)
                    }
                  })
              }
            })
        } else if (res.data.code == 1) {
          //成功
          resole(res.data)
        } else {
          //失败
          reject(res.data)
        }
      }).catch(res => {
        reject(res.data)
      })
  }
})

}) }

module.exports = {fetch, method} 在页面中调用

var network=require("../../utils/network/network.js") var wxapi = require("../../utils/network/base.js").wxapi; var api = require("../../utils/network/config.js").api;

Page({

onLoad: function () {

  network.fetch({
     url: api.course_detail,
     data: {
         id: 18
     },
  })
  .then(res=>{
    console.log(res);
  })
  .catch(res=>console.log(res))
  },

}

})

接口地址,放在config.js中

const api={ base_url: 'https://****.com', login: '/v1/user/login', course_detail: '/v1/course/detail', }

module.exports={api}

base.js 将微信的api封装成promise形式

function wxapi(function_name, obj) { return new Promise((resole, reject)=>{ wx[function_name]({ ...obj, success: res => resole(res), faile:res=>reject(res) }) }) }

module.exports = {wxapi}

转载 - www.shanhuxueyuan.com/news/detail…