TENCENT\ivinwu 169c6cc4dc update readme
2018-11-22 20:54:22 +08:00
2018-04-19 15:27:33 +08:00
2018-09-24 21:58:20 +08:00
2018-02-02 10:38:18 +08:00
2018-09-24 10:41:10 +08:00
2017-07-31 17:00:38 +08:00
2018-11-22 20:54:22 +08:00

logo

weRequest

解决繁琐的小程序会话管理,一款自带登录态管理的网络请求组件。

GitHub forks GitHub stars GitHub watchers Packagist

目标

让业务逻辑更专注不用再关注底层登录态问题。小程序对比以往的H5登录态管理逻辑要复杂很多。通过weRequest这个组件,希望能帮助开发者把更多精力放在业务逻辑上,而登录态管理问题只需通过一次简单配置,以后就不用再花精力管理了。

怎么使用

var weRequest= require('../weRequest');

// 初始化配置
weRequest.init({
    // 关于配置内容,将在后文详述
    // 此处暂时省略...
})

// 发起请求
weRequest.request({
    url: 'order/detail',
    data: {
        id: '107B7615E04AE64CFC10'
    },
    success: function (data) {
		// 省略...
    }
})
  • 引入weRequest组件
  • 初始化组件配置
  • 就像使用wx.request那样去使用它

为什么需要它

登录时序图

上图是小程序官方文档中的登录时序图。此图涵盖了前后端,详细讲解了包括登录态的生成,维护,传输等各方面的问题。

具体到业务开发过程中的前端来说,我认为上图还不够完整,于是我画了下面这张以前端逻辑为出发点的、包含循环的流程图。 我认为前端每一次发起网络请求,跟后台进行数据交互,都适用于下图的流程

  • hasChecked 用一状态标识本生命周期内是否执行过wx.checkSession,判断该标识,若否,开始执行wx.checkSession,若是,进入下一步
  • wx.checkSession() 调用接口判断登录态是否过期,若是,重新登录;若否,进入下一步

wx.checkSession()是小程序提供的检测登录态是否过期的接口,生命周期内只需调用一次即可。用户越久未使用小程序,用户登录态越有可能失效。反之如果用户一直在使用小程序,则用户登录态一直保持有效。具体时效逻辑由微信维护,对开发者透明

  • wx.getStorage(session) 尝试获取本地的session。如果之前曾经登录过,则能获取到;否则,本地无session
  • wx.login() 小程序提供的接口,用于获取codecode有效期为5分钟
  • wx.request(code)code通过后台提供的接口,换取session
  • wx.setStorage(session) 将后台接口返回的session存入到localStorage以备后续使用
  • wx.request(session) 真正发起业务请求,请求中带上session
  • parse(data) 对后台返回的数据进行预解析,若发现登录态失效,则重新执行登录;若成功,则真正获取到业务数据

只要遵循上图的流程,我们就无需在业务逻辑中关注登录态的问题了,相当于把登录态的管理问题耦合到了发起网络请求当中,本组件则完成了上述流程的封装,让开发者不用再关心以上逻辑,把精力放回在业务的开发上。

演示DEMO

自动带上登录态参数

可以看到,通过weRequest发出的请求,将会自动带上登录态参数。 对应的流程为下图中红色的指向: 自动带上登录态参数

没有登录态时,自动登录

当本地没有登录态时,按照流程图,weRequest将会自动执行wx.login()后的一系列流程,得到code并调用后台接口换取session储存在localStorage之后重新发起业务请求。 对应的流程为下图中红色的指向:

登录态过期时,自动重新登录

对后台数据进行预解析之后,发现登录态过期,于是重新执行登录流程,获取新的session之后,重新发起请求。 对应的流程为下图中红色的指向: 登录态过期时,自动重新登录

文档

.init(OBJECT)

对组件进行初始化配置,使用组件发起请求前必须进行至少一次的配置

OBJECT参数说明

参数名 类型 必填 默认值 说明
sessionName String session 储存在localStorage的session名称且CGI请求的data中会自动带上以此为名称的session值可不配置默认为session
urlPerfix String or Function 请求URL的固定前缀如果配置了后续请求的URL都会自动加上这个前缀如果是函数则为函数的返回值
loginTrigger Function 触发重新登录的条件参数为CGI返回的数据返回需要重新登录的条件
codeToSession Object 用code换取session的CGI配置
reLoginLimit Int 3 登录重试次数,当连续请求登录接口返回失败次数超过这个次数,将不再重试登录
successTrigger Function 触发请求成功的条件参数为CGI返回的数据返回接口逻辑成功的条件
successData Function 成功之后返回数据参数为CGI返回的数据返回逻辑需要使用的数据
errorTitle String/Function 操作失败 接口逻辑失败时,错误弹窗的标题
errorContent String/Function 接口逻辑失败时,错误弹窗的内容
errorCallback Function 当出现接口逻辑错误时,会执行统一的回调函数,这里可以做统一的错误上报等处理
doNotCheckSession Boolean false 是否需要调用checkSession验证小程序的登录态过期若业务不需要使用到session_key则可配置为true
reportCGI Function 接口返回成功之后,会执行统一的回调函数,这里可以做统一的耗时上报等处理
mockJson Object 可为接口提供mock数据
globalData Object/Function 所有请求都会自动带上这里的参数
sessionExpireTime Int null 为用户登陆态设置本地缓存时间单位为ms一旦过期直接废弃缓存中的登陆态
sessionExpireKey String sessionExpireKey 如果为用户登陆态设置了本地缓存时间则过期时间将以此值为key存储在Storage中
codeToSession参数说明
参数名 类型 必填 默认值 说明
url String CGI的url
method String GET 调用改CGI的方法
codeName String code CGI中传参时存放code的名称
data Object 登录接口需要的其他参数
success Function 接口返回成功的函数需要返回session的值
fail Function code换取session的接口逻辑出错时执行的函数若配置了此函数则不再默认弹窗报错
reportCGI返回参数说明
参数名 类型 说明
name String 调用的接口名字可在request接口的report字段配置
startTime Int 发起请求时的时间戳
endTime Int 请求返回时的时间戳
request Function 请求方法,可用于上报

示例代码

weRequest.init({
    // [可选] 存在localStorage的session名称且CGI请求的data中会自动带上以此为名称的session值可不配置默认为session
    sessionName: "session",
    // [可选] 请求URL的固定前缀可不配置默认为空
    urlPerfix: "https://www.example.com/",
    // [必填] 触发重新登录的条件res为CGI返回的数据
    loginTrigger: function (res) {
        // 此处例子当返回数据中的字段errcode等于-1会自动触发重新登录
        return res.errcode == -1;
    },
    // [必填] 用code换取session的CGI配置
    codeToSession: {
        // [必填] CGI的URL
        url: 'user/login',
        // [可选] 调用改CGI的方法可不配置默认为GET
        method: 'GET',
        // [可选] CGI中传参时存放code的名称此处例子名称就是code可不配置默认值为code
        codeName: 'code',
        // [可选] 登录接口需要的其他参数;可不配置,默认为{}
        data: {},
        // [必填] CGI中返回的session值
        success: function (res) {
            // 此处例子CGI返回数据中的字段session即为session值
            return res.session;
        },
        // [可选] 接口失败的回调,可不配置,默认为弹窗报错
        fail: function(obj, res) {

        }
    },
    // [可选] 登录重试次数当连续请求登录接口返回失败次数超过这个次数将不再重试登录可不配置默认为重试3次
    reLoginLimit: 2,
    // [必填] 触发请求成功的条件
    successTrigger: function (res) {
        // 此处例子当返回数据中的字段errcode等于0时代表请求成功其他情况都认为业务逻辑失败
        return res.errcode == 0;
    },
    // [可选] 成功之后返回数据;可不配置
    successData: function (res) {
        // 此处例子返回数据中的字段data为业务接受到的数据
        return res.data;
    },
    // [可选] 当CGI返回错误时弹框提示的标题文字
    errorTitle: function(res) {
        // 此处例子当返回数据中的字段errcode等于0x10040730时错误弹框的标题是“温馨提示”其他情况下则是“操作失败”
        return res.errcode == 0x10040730 ? '温馨提示' : '操作失败'
    },
    // [可选] 当CGI返回错误时弹框提示的内容文字
    errorContent: function(res) {
        // 此处例子返回数据中的字段msg为错误弹框的提示内容文字
        return res.msg ? res.msg : '服务可能存在异常,请稍后重试'
    },
    // [可选] 当出现CGI错误时统一的回调函数这里可以做统一的错误上报等处理
    errorCallback: function(obj, res) {
        // do some report
    },
    // [可选] 是否需要调用checkSession验证小程序的登录态过期可不配置默认为false
    doNotCheckSession: true,
	// [可选] 上报耗时的函数name为上报名称startTime为接口调用开始时的时间戳endTime为接口返回时的时间戳
    reportCGI: function(name, startTime, endTime, request) {
        //wx.reportAnalytics(name, {
        //    time: endTime - startTime
        //});
        //request({
        //    url: 'reportCGI',
        //    data: {
        //        name: name,
        //        cost: endTime - startTime
        //    },
        //    fail: function() {
        //
        //    }
        //})
        console.log(name + ":" + (endTime - startTime));
    },
	// [可选] 提供接口的mock若不需使用请设置为false
    mockJson: require("../../mock.json"),
    // [可选] 所有请求都会自动带上globalData里的参数
    globalData: function() {
        return {
            version: getApp().version
        }
    },
    // [可选] session本地缓存时间(单位为ms),可不配置,默认不设置本地缓存时间
    sessionExpireTime: 24 * 60 * 60 * 1000,
    // [可选] session本地缓存时间存在Storage中的名字可不配置默认为 sessionExpireKey
    sessionExpireKey: "sessionExpireKey"
})

.request(OBJECT)

带上登录态发起一个请求,参数大部分与wx.request一致

OBJECT参数说明

参数名 类型 必填 默认值 说明 是否与wx.request不一致
url String 开发者服务器接口地址若在init()时有配置urlPerfix则这里会自动拼接前缀
data Object/String 请求的参数
header Object 设置请求的 headerheader 中不能设置 Referer。
method String GET 需大写有效值OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
dataType String json 如果设为json会尝试对返回的数据做一次 JSON.parse
beforeSend Function 发起请求前执行的函数
success Function 收到开发者服务成功返回,且执行successTrigger成功后的回调函数,参数为successData返回的参数
fail Function 接口调用失败,或执行successTrigger失败后的回调函数,若这里有配置,则不再默认弹窗报错
complete Function 接口调用结束的回调函数(调用成功、失败都会执行)
showLoading Boolean false 请求过程页面是否展示全屏的loading
report String 接口请求成功后将自动执行init()中配置的reportCGI函数其中的name字段值为这里配置的值

示例代码

weRequest.request({
    url: 'order/detail',
    showLoading: true,
    report: 'detail',
    data: {
        id: '123'
    },
    success: function (data) {
        console.log(data);
    },
    fail: function(res) {
    }
})

.uploadFile(Object)

带上登录态,将本地资源上传到开发者服务器,客户端发起一个 HTTPS POST 请求,其中 content-type 为 multipart/form-data参数大部分与wx.uploadFile一致

OBJECT参数说明

参数名 类型 必填 默认值 说明 是否与wx.uploadFile不一致
url String 开发者服务器接口地址若在init()时有配置urlPerfix则这里会自动拼接前缀
filePath String 要上传文件资源的路径
name String 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
header Object 设置请求的 headerheader 中不能设置 Referer。
formData Object HTTP 请求中其他额外的 form data
beforeSend Function 发起请求前执行的函数
success Function 收到开发者服务成功返回,且执行successTrigger成功后的回调函数,参数为successData返回的参数
fail Function 接口调用失败,或执行successTrigger失败后的回调函数,若这里有配置,则不再默认弹窗报错
complete Function 接口调用结束的回调函数(调用成功、失败都会执行)
showLoading Boolean false 请求过程页面是否展示全屏的loading
report String 接口请求成功后将自动执行init()中配置的reportCGI函数其中的name字段值为这里配置的值

示例代码

wx.chooseImage({
    count: 1,
    success: function (res) {
        weRequest.uploadFile({
            url: 'upload/img',
            filePath: res.tempFilePaths[0],
            name: 'pic',
            showLoading: "提交中",
            success(data){
                console.log(data.imgPath);
            }
        })
    }
})

.getSession()

[return String] 获取本地缓存中用户票据的值

.getConfig()

[return Object] 获取weRequest的配置。返回的Object内容如下

参数名 类型 说明
urlPerfix String or Function 在组件初始化时传入的请求URL的固定前缀
sessionExpireTime Int 在组件初始化时传入的用户登陆态设置本地缓存时间
sessionExpireKey String 在组件初始化时传入的用户登陆态本地缓存时间Storage的key
sessionExpire Int 用户登陆态本地缓存过期的时间戳

.login()

[不建议使用] 在不发起业务请求的情况下,单独执行登录逻辑

.setSession(String)

[不建议使用] 设置用户票据的值

FAQ

我希望在请求时候页面能出现最简单的loading状态该怎么办

只需要在请求的时候,加上参数showLoading: true即可,如:

weRequest.request({
    url: 'order/detail',
    showLoading: true,
    data: {
        id: '123'
    },
    success: function (data) {
        console.log(data);
    }
})

当然如果你希望使用个性化的loading样式你可以直接使用beforeSend参数来进行自定义展示个性化的loading并且在complete的时候将它隐藏。

某些请求在返回错误时,我不希望触发通用的错误提示框,而想用特别的逻辑去处理,该怎么办?

只需要在请求的时候,加上参数fail: function(){ ... }即可,如:

weRequest.request({
    url: 'order/detail',
    slience: true,
    data: {
        id: '123'
    },
    success: function (data) {
        console.log(data);
    },
    fail: function(res) {
        console.log(res);
    }
})

此时如果接口返回错误码将触发这里定义的fail函数且默认错误弹框将不会出现。

为什么工具在发起请求之前不主动去判断第三方session是否过期而要通过接口结果来判断这不是浪费了一次请求往返吗

每个小程序对于自身生成的session都有自己的一套管理方案微信官方也没有指明一套通用的方案来要求开发者仅仅要求了应该保证其安全性且不应该设置较长的过期时间。 原文如下:

通过 wx.login() 获取到用户登录态之后,需要维护登录态。开发者要注意不应该直接把 session_key、openid 等字段作为用户的标识或者 session 的标识,而应该自己派发一个 session 登录态(请参考登录时序图)。对于开发者自己生成的 session应该保证其安全性且不应该设置较长的过期时间。session 派发到小程序客户端之后,可将其存储在 storage ,用于后续通信使用。

因此不能要求所有后端接口都要返回session的过期时间给前端甚至有些后端逻辑对于session的管理是动态的会随调用情况来更新session的生命周期这样的话逻辑就更复杂了。但是无论任何一种管理策略都必须会有兜底策略即前端传入过期的session后端必须要返回特定标识告知前端此session过期。因此作为一个通用的工具组件我需要确保更多的开发者能够低门槛地使用所以并没有针对各种特别策略去优化而且我相信对于正常使用小程序的用户来说登录态过期是一个相对低概率的事情对整体效率性能来说是微乎其微的使用通用的兜底策略去应对这种情况我认为已经是足够的了。

Description
No description provided
Readme MIT 3 MiB
Languages
JavaScript 83%
TypeScript 17%