继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

微信小程序踩坑指南

拉丁的传说
关注TA
已关注
手记 573
粉丝 126
获赞 789

作者:sichen

原文链接:https://segmentfault.com/a/1190000015281442

最近因为公司业务一直在做微信小程序的项目,趁此机会将最近踩过的一些坑总结记录下


微信小程序登陆流程

https://img.mukewang.com/5b21badd000163a106230630.jpg
  1. 前端调用wx.login(),获取临时登录凭证 code

  2. 通过wx.request()将code发给服务器(需要后端创建接口接收code)

  3. 后端进行登录凭证校验,入参为(appid,secret,js_code,grant_type)

appid          小程序唯一标识
secret         小程序的 app secret
js_code         登录时获取的 code
grant_type    填写为 authorization_code
  1. 登陆凭证校验通过,从微信服务器换取openid和session_key

openid    用户唯一标识
session_key    会话密钥

openid 是用户唯一标识,但不建议直接用做后端服务器的各用户标示符。
session_key 是针对用户数据进行加密签名的密匙。session_key 在文件校验,获取用户具体信息时均需使用

一般为了安全起见,这两个数据都不会发往客户端。

  1. 后端将session_key处理之后,返回前端一个处理后的一个字符串作为用户的登陆标识,一般以token的形式。(自定义登陆态与openid session_key相关)

  2. 前端接收到token,储存到localStorage中,每次向服务器请求数据的时候带上,作为服务器识别用户的凭证。

  3. 后续用户进入小程序时,首先调用 wx.checkSession() 检测登陆态,如果失败,重新发起登陆流程。


//app.jsconst NOLOGINCODE = 1000003  //未登录const SUCCESS = 1000001 //成功App({  onLaunch: function () {    var loginFlag = wx.getStorageSync('sessionId');    var that = this;    if (loginFlag) {      // 检查 session_key 是否过期
      wx.checkSession({        // session_key 有效(未过期)
        success: function () {          var userInfo = wx.getStorageSync('wxUserInfo')          if (userInfo) {
            that.globalData.hasUserInfo = true
          }
        },        // session_key 过期
        fail: function () {          // session_key过期,重新登录
          that.doLogin();
        }
      });
    } else {      // 无skey,作为首次登录
      this.doLogin();
    }
  },
  doLogin() {    this.log().then(res => {      this.$post('/auth', { code: res.code, }, false).then(data => {
        wx.setStorageSync('sessionId', data.sessionId);
      })
    })
  },  /**
   *微信登录 获取code值,并将code传递给服务器
   * @returns
   */
  log() {    return new Promise(resolve => {
      wx.login({
        success(res) {          if (res.errMsg === "login:ok") {
            resolve(res)
          } else {
            wx.showToast({              title: '微信登录失败',              icon: 'none',              duration: 1200
            })
          }
        },
        fail() {
          wx.showToast({            title: '微信登录接口调用失败',            icon: 'none',            duration: 1200
          })
        }
      })
    })
  },  globalData: {    baseurl: 'https://www.fake.shop'
  }
})

补充


微信小程序中网络请求的api是wx.request(),但是这个请求是个异步回调的形式,每次发请求都要写好长一串,而且如果是嵌套的发请求,就会发现代码写的及其臃肿,所以将其 Promisefy是及其有必要的。
代码如下:

 $get(url, data = {}, needToken = true) {    let SUCCESS = 200
    var that = this
    needToken ? (data.token = wx.getStorageSync('ToKen')) : ''
    return new Promise((resolve, reject) => {
      wx.request({        url: that.globalData.baseurl + url,        method: "GET",        header: {          'content-type': 'application/json'
        },        data: data,
        success(e) {          if (e.data.code == SUCCESS) {
            resolve(e.data)            return
          }

        },
        fail(e) {
          wx.showModal({            title: '提示',            content: '请求失败',            showCancel: false
          })
          reject(e)
        }
      })
    })
  },
  $post(url, data = {}, needToken = true) {    let that = this
    let SUCCESS = 200
    let TimeOut = 1000
    var that = this
    needToken ? (data.token = wx.getStorageSync('ToKen')) : ''
    return new Promise((resolve, reject) => {
      wx.request({        url: that.globalData.baseurl + url,        method: "POST",        //此处可以根据接口文档设置header头
        // header: { 
        //   'content-type': 'application/x-www-form-urlencoded'
        // },
        data: data,
        success(e) {          if (e.statusCode == SUCCESS) {            if (e.data.code == SUCCESS) {
              resolve(e.data)
            }            else {
              reject(e)
              wx.showModal({                title: '提示',                content: e.data.msg,                showCancel: false,                success: function (res) {                  if (res.confirm) {                    if (e.data.code == TimeOut) { //根据实际业务返回的code码判断是否过期
                      // 登录过期
                      that.doLogin();
                    }
                  }
                }
              })
            }
          } else {
            wx.showModal({              title: '提示',              content: e.data.error,              showCancel: false
            })
            reject(e)
          }
        },
        fail(e) {          console.log(e)
          wx.showModal({            title: '提示',            content: '请求失败',            showCancel: false
          })
          reject(e)
        },
        complete(e) {
        }
      })

    })
  },

先这么多吧,好累啊,溜了溜了,剩下的留着以后更


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP