小程序模板網(wǎng)

微信小程序踩坑指南

發(fā)布時間:2019-01-02 09:45 所屬欄目:小程序開發(fā)教程

最近因為公司業(yè)務(wù)一直在做微信小程序的項目,趁此機會將最近踩過的一些坑總結(jié)記錄下。

微信小程序登陸相關(guān)


 

  • 前端調(diào)用wx.login(),獲取臨時登錄憑證 code
  • 通過wx.request()將code發(fā)給服務(wù)器(需要后端創(chuàng)建接口接收code)
  • 后端進行登錄憑證校驗,入?yún)?appid,secret,js_code,grant_type)

appid 小程序唯一標(biāo)識 secret 小程序的 app secret js_code 登錄時獲取的 code grant_type 填寫為 authorization_code

  • 登陸憑證校驗通過,從微信服務(wù)器換取openid和session_key

openid 用戶唯一標(biāo)識 session_key 會話密鑰

openid 是用戶唯一標(biāo)識,但不建議直接用做后端服務(wù)器的各用戶標(biāo)示符。 session_key 是針對用戶數(shù)據(jù)進行加密簽名的密匙。session_key 在文件校驗,獲取用戶具體信息時均需使用

一般為了安全起見,這兩個數(shù)據(jù)都不會發(fā)往客戶端。

  • 后端將session_key處理之后,返回前端一個處理后的一個字符串作為用戶的登陸標(biāo)識,一般以token的形式。(自定義登陸態(tài)與openid session_key相關(guān))
  • 前端接收到token,儲存到localStorage中,每次向服務(wù)器請求數(shù)據(jù)的時候帶上,作為服務(wù)器識別用戶的憑證。
  • 后續(xù)用戶進入小程序時,首先調(diào)用 wx.checkSession() 檢測登陸態(tài),如果失敗,重新發(fā)起登陸流程。
//app.js
const 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傳遞給服務(wù)器
   * @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: '微信登錄接口調(diào)用失敗',
            icon: 'none',
            duration: 1200
          })
        }
      })
    })
  },
  globalData: {
    baseurl: 'https://www.fake.shop'
  }
})
復(fù)制代碼

網(wǎng)絡(luò)請求封裝


微信小程序中網(wǎng)絡(luò)請求的api是wx.request(),但是這個請求是個異步回調(diào)的形式,每次發(fā)請求都要寫好長一串,而且如果是嵌套的發(fā)請求,就會發(fā)現(xiàn)代碼寫的及其臃腫,所以將其 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",
        //此處可以根據(jù)接口文檔設(shè)置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) { //根據(jù)實際業(yè)務(wù)返回的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) {
        }
      })

    })
  },
復(fù)制代碼

微信公共號支付(微信瀏覽器)


雖然是寫小程序踩坑指南,但是在微信內(nèi)的H5頁面支付和小程序內(nèi)掉起支付還是有相似之處的,順便記錄一下。

應(yīng)用場景

  • 已有 H5 商城網(wǎng)站,用戶通過消息或掃描二維碼在微信內(nèi)打開網(wǎng)頁時,可以調(diào)用微信支付完成下單購買的流程。
準(zhǔn)備

UnionID:為了識別用戶,每個用戶針對每個公眾號會產(chǎn)生一個安全的 OpenID,如果需要在多公眾號、移動應(yīng)用之間做用戶共通,則需前往微信開放平臺,將這些公眾號和應(yīng)用綁定到一個開放平臺賬號下,綁定后,一個用戶雖然對多個公眾號和應(yīng)用有多個不同的 OpenID,但他對所有這些同一開放平臺賬號下的公眾號和應(yīng)用,只有一個 UnionID 網(wǎng)頁授權(quán): 一些復(fù)雜的業(yè)務(wù)場景下,需要以網(wǎng)頁的形式提供服務(wù),通過網(wǎng)頁授權(quán)可以獲取用戶的openid(注:獲取用戶的 OpenID 是無需用戶同意的,獲取用戶的基本信息則需用戶同意) 微信 JS-SDK:是開發(fā)者在網(wǎng)頁上通過 JavaScript 代碼使用微信原生功能的工具包,開發(fā)者可以使用它在網(wǎng)頁上錄制和播放微信語音、監(jiān)聽微信分享、上傳手機本地圖片、拍照等許多能力。

業(yè)務(wù)流程時序圖

 

 

主要流程
  • 網(wǎng)頁內(nèi)引入jssdk,主要有兩種
    • 在需要調(diào)用 JS 接口的頁面引入如下 JS 文件:res.wx.qq.com/open/js/jwe… JSSDK 使用步驟
    • 模塊引入: 直接引入npm包weixin-js-sdk
    • npm install weixin-js-sdk ;

    • var wx = require('weixin-js-sdk');

  • 網(wǎng)頁授權(quán)
    • 我的理解就是網(wǎng)頁授權(quán)主要是為了使在微信瀏覽器里面打開的第三方網(wǎng)頁,可以跟微信公共號以及用戶的微信相關(guān)聯(lián)的操作,最終獲取用戶在該公共號下的openid.
    • 網(wǎng)站應(yīng)用微信登錄是基于 OAuth2.0 協(xié)議標(biāo)準(zhǔn)構(gòu)建的微信 OAuth2.0 授權(quán)登錄系統(tǒng)。獲取 openid 分為兩步
      • 前端通過跳轉(zhuǎn)網(wǎng)址獲取 code,然后將code發(fā)送給后端
      • 后端然后根據(jù) code 獲取 openid。

code的獲取

  • 在微信公眾號請求用戶網(wǎng)頁授權(quán)之前,開發(fā)者需要先到公眾平臺官網(wǎng)中的 “開發(fā) - 接口權(quán)限 - 網(wǎng)頁服務(wù) - 網(wǎng)頁帳號 - 網(wǎng)頁授權(quán)獲取用戶基本信息” 的配置選項中,修改授權(quán)回調(diào)域名。本例中回調(diào)域名為www.foo.com
  • 業(yè)務(wù)流程 舉例: 支付頁面地址: payUrl => "www.foo.com/pay"
    1. 要跳轉(zhuǎn)到支付頁面時,如果是微信瀏覽器直接跳轉(zhuǎn)href(辦法有很多可以重定向也可以location.href)到 "open.weixin.qq.com/connect/oau…"+ appid +"&redirect_uri="+ URLEncoder.encode(payUrl) +"&response_type=code&scope=snsapi_base&state=123#wechat_redirect"
    2. 系統(tǒng)會自動跳轉(zhuǎn)到 payUrl 并且返回一個參數(shù) code 例如=> "www.aa.com/pay?code=aa…"
    3. 然后讀取下code發(fā)送后端就ok了,這個大家應(yīng)該都會吧。 注:

URLEncoder.encode(payUrl)是非常有必要的 state參數(shù): 用于保持請求和回調(diào)的狀態(tài),授權(quán)請求后原樣帶回給第三方。該參數(shù)可用于防止 csrf 攻擊(跨站請求偽造攻擊),建議第三方帶上該參數(shù),可設(shè)置為簡單的隨機數(shù)加 session 進行校驗 后端獲取openid的原因: 因為我是前端,不想搞這個(開玩笑的


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://22321a.com/wxmini/doc/course/25060.html 復(fù)制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢