1. 程式人生 > >微信小程式的詳細登入(上)

微信小程式的詳細登入(上)

前段時間釋出了一個微信小程式的簡單登入,那段時間我一直在忙著專案,有一天,我清閒下來準備進入小程式群裡面看一下來著,剛好有人問問題了,我一看這哥們的問題好像是我寫的東西啊,我感覺是時候秀一波了,是時候展現我真正的技術了。我當時正在醞釀如何無形裝逼時。這時候出現了一個打臉的。他說這種登入方式不可以使用了,當時我就有點不信了,結果自己測試了真的不可以使用了,沒辦法,只能更新一版新的了,說實話,那臉打的比較響亮啊快哭了,於是乎就有了今天就幫大家更新了一版。好了,閒話扯到這裡結束了。

原來的簡單登入是直接在前臺獲取openid,但是呢微信官方發現這個洞以後就給填了,不讓你們玩了,你們在這麼玩下去生態圈就沒辦法維持了,官方直接在安全域名處禁止新增https://api.weixin.qq.com,但是呢以前新增的使用者還是可以用的。

如上圖顯示。

好了廢話不多少,直接擼程式碼,同時在這裡整理了一些專案中開發中遇到的一些經驗分享給大家。

//app.js
// 這裡是呼叫公共函式庫
var util = require('./utils/util.js')
App({

    /**
    * 當小程式初始化完成時,會觸發 onLaunch(全域性只觸發一次)
    */
    onLaunch: function (options) {

        // 呼叫API從本地快取中獲取資料
        var that = this
        var logs = wx.getStorageSync('logs') || []
        logs.unshift(Date.now())
        wx.setStorageSync('logs', logs)

    },

    /**
    * 當小程式啟動,或從後臺進入前臺顯示,會觸發 onShow
    */
    onShow: function (options) {
        
        var that = this,
        // scenes是場景值它的型別是整形
        scenes = options.scene,
        // sid是引數,建議相容ios和android的時候強轉換為整形
        sid = Number(options.query.sid)

        // 獲取使用者資訊
        that.getUserInfo(function (userInfo) {
            // 判斷場景是否是從公眾號進入(這裡的意思是如果使用者從公眾號的自定義選單進入的話且引數sid為1的話觸發什麼方法)
            // 獲取場景值在onLaunch方法中也可以獲取到,但是呢由於業務要求我們的這個方法需要使用者進入就會觸發
            // 各位可以根據需求去決定在哪裡獲取合適一些,onLaunch是小程式未關閉的情況下只執行一次,所以各位一定要考慮清楚
            if (scenes === 1035 && sid === 1) {
                // 這裡是從什麼場景下要執行的方法
            }
        })
    },

    /**
    * 獲取使用者資訊
    */
    getUserInfo: function (cb) {
        var that = this
    
        if (this.globalData.userInfo) {
            
            typeof cb == "function" && cb(this.globalData.userInfo)
        
        } else {
            
            // 呼叫登入介面
            wx.login({
                success: function (res) {
                    
                    // 登入成功
                    // 在這裡登入的時候會返回一個登入憑證,以前是傳送一次請求換一個,現在好像是登入憑證有5分鐘的有效時間
                    // 從這種情況來看微信小程式的發展還是不錯的,以前估計沒多少人訪問,現在訪問量上去後後臺的佈局都重新架構了
                    var code = res.code// 登入憑證
                    
                    // 獲取使用者資訊
                    wx.getUserInfo({
                        // 當你獲取使用者資訊的時候會彈出一個彈框是否允許授權
                        
                        // 這裡點選允許觸發的方法
                        success: function (res2) {
                        
                            that.globalData.userInfo = res2.userInfo

                            // 準備資料(下面的這些引數都是必須引數,請不要問為什麼,看文件去吧)
                            var data = { encryptedData: res2.encryptedData, iv: res2.iv, code: code }
                            
                            // 請求自己的伺服器(在這裡我結合promise封裝了一下request請求,下面會把方法給大家分享一下)
                            util.commonAjax('方法名', 1, data)
                            .then(function (resolve) {
                                // 這裡自然不用解釋了,這是介面返回的引數
                                if (resolve.data.status === '200') {
                                    // 成功
                                    wx.setStorageSync('userInfo',  resolve.data.data)
                                    // 新手們注意一下,記得把下面這個寫到這裡,有好處。
                                    typeof cb == "function" && cb(that.globalData.userInfo)
                                } else {
                                    // 失敗
                                }
                            })
                        },
                        
                        // 這裡是點選拒絕觸發的方法
                        fail: function (res2) {
                            // 在這裡做一下相容,有些同行業的使用者會點選拒絕玩一玩看你們的小程式是否存在bug,
                            // 所以在這裡還是加上下面這兩行程式碼吧,開啟微信小程式的設定,允許小程式重新授權的頁面
                            wx.openSetting({
                                success: (res) => {
                                    // 下面的程式碼格式按照我的寫,不要看工具列印的什麼,在這裡提醒大家一句,有時候不能相信開發者工具,因為
                                    // android和ios還有工具底層的js庫是不同的,有些時候坑的你是一點脾氣也沒有,所以大家注意一下,
                                    // 不相信的慢慢的去自己跳坑吧
                                    if (res.authSetting["scope.userInfo"]) {
                                        // 進入這裡說明使用者重新授權了,重新執行獲取使用者資訊的方法
                                        that.getUserInfo()
                                    }
                                }
                            })
                        }
                    })
                }
            })
        }
    },

    /**
    * 全域性變數配置(在這裡放一些常量和配置檔案,如果公共引數多的話大家也可以去重新佈局一個檔案,在裡面進行設定)
    */
    globalData: {
        userInfo: null,
        url: '這是介面的url'
    }
})

// 下面是util.js的東西

/**
 * request請求封裝
 * url   傳遞方法名
 * types 傳遞方式(1,GET,2,POST)
 * data  傳遞資料物件
 */
function commonAjax(url, types, data) {
    
    // 獲取公共配置
    var app = getApp()
  
    // 公共引數(一般寫介面的時候都會有些公共引數,你可以事先把這些引數都封裝起來,就不用每次呼叫方法的時候再去寫,)
    var d = {
        token: '123456789',// 例如:這是我們自己的驗證規則
    }
  
    // 合併物件(公共引數加傳入引數合併物件) mergeObj物件在下面
    var datas = mergeObj(d, data)

    // 這是es6的promise版本庫大概在1.1.0開始支援的,大家可以去歷史細節點去看一下,一些es6的機制已經可以使用了
    var promise = new Promise(function (resolve, reject, defaults) {
    // 封裝reuqest
    wx.request({
      url: app.globalData.url + url,
      data: datas,
      method: (types === 1) ? 'GET' : 'POST',
      header: (types === 1) ? { 'content-type': 'application/json' } : { 'content-type':'application/x-www-form-urlencoded'},
      success: resolve,
      fail: reject,
      complete: defaults,
    })
  });
  return promise;
}

/**
 * object 物件合併
 * o1     物件一
 * o2     物件二
 */
function mergeObj(o1, o2) {
  for (var key in o2) {
    o1[key] = o2[key]
  }
  return o1;
}

function formatTime(date) {
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var day = date.getDate()

  var hour = date.getHours()
  var minute = date.getMinutes()
  var second = date.getSeconds()


  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

function formatNumber(n) {
  n = n.toString()
  return n[1] ? n : '0' + n
}

module.exports = {
  formatTime: formatTime,
  commonAjax: commonAjax,
}

上面的一些封裝,大家可以根據自己的喜好去修改,畢竟一個人一個風格嗎,程式碼寫的有一些亂,大家見諒一下,因為專案有點亂,我現在也有點頭大,不知道該把哪些東西歸為一類講個大家,所以顯得有點亂,但是呢,上面的程式碼包括封裝都是線上經過實戰檢測沒問題的程式碼,至於後臺的程式碼會在下個帖子中發表。


 付一段程式碼,望各位參考一下