/weRequest

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

Primary LanguageTypeScriptMIT LicenseMIT

weRequest

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

目标

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

如何安装

a) 通过npm安装

npm install --save we-request@2.x.x

b) 或直接下载build/weRequest.min.js放到小程序包内

怎么使用

1) 引入weRequest组件

1.a)ES6模式

import weRequest from 'we-request';

// 若下载文件到本地,则直接引入对应文件,具体路径自己根据情况修改
// import weRequest from '../lib/weRequest.min'

1.b) commonJs 模式

const weRequest= require('we-request');

// 若下载文件到本地,则直接引入对应文件,具体路径自己根据情况修改
// const weRequest = require('../lib/weRequest.min');

2) 初始化组件配置

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

3) 就像使用wx.request那样去使用它

// 发起请求
weRequest.request({
    url: 'order/detail',
    data: {
        id: '107B7615E04AE64CFC10'
    },
    success: function (data) {
        // 省略...
    }
})

// 同时也支持Promise形式使用
weRequest.request({
    url: 'order/detail',
    data: {
      id: '107B7615E04AE64CFC10'
    }
}).then((data)=>{
    // 省略...
})

使用贴士

正常情况下组件只需要init一次即可,因此初始化可以封装在一个文件中:

// 举例: 以下代码封装在 util/weRequest.js

import weRequest from 'we-request';

weRequest.init({
  // ...
});

export default weRequest;

后续业务逻辑直接引用封装好的文件即可使用:

import weRequest from 'util/weRequest';

weRequest.request({
  // ...
})

为什么需要它

参看原理介绍

2.0 版本与 1.0 版本的区别

从原理介绍中可知,1.0版本在本地无登录态的场景下,若要调用业务请求,首先需要执行一次登录流程,在拿到登录态后,才能真正地发起业务请求,整个过程涉及到多个网络来回。

而2.0版本针对这里进行了一个优化,在后端接口满足的前提下,2.0的版本在发起业务请求时,根据当下情况可能会附带登录态,也可能会附带wx.login()返回的code,后端根据场景可能会先执行登录流程,然后完成业务逻辑后,将登录态和业务数据一同返回,以节省一次网络的来回。也就是说,对于2.0版本而已,不需要专门的登录接口了,所有的业务请求接口都需要兼容登录逻辑。

文档

.init(OBJECT)

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

OBJECT参数说明

参数名 类型 必填 默认值 说明
sessionName String session 所有请求会带上以此为key的票据;可不配置,票据名默认为session
codeName String code CGI中传参时,存放code的名称;可不配置,默认值为code
urlPerfix String/Function 请求URL的固定前缀,如果配置了,后续请求的URL都会自动加上这个前缀,如果是函数,则为函数的返回值
loginTrigger Function 触发重新登录的条件;参数为CGI返回的数据,返回需要重新登录的条件
reLoginLimit Int 3 登录重试次数,当连续请求登录接口返回失败次数超过这个次数,将不再重试登录
getSession Function 后端在接口中返回登录成功后的第三方登录态
successTrigger Function 触发请求成功的条件;参数为CGI返回的数据,返回接口逻辑成功的条件
successData Function 成功之后返回数据;参数为CGI返回的数据,返回逻辑需要使用的数据
errorHandler Function 自定义错误处理函数,若被定义,则默认的报错弹窗将不再自动发生,下方的errorTitle和errorContent将被忽略
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中
doNotUseQueryString Boolean false 默认情况下,POST请求,登陆态除了带在请求body中,也会带在queryString上,如果配置了这个为true,则登陆态不带在queryString中
setHeader Object/Function 所有请求的header都会带上此对象中的字段
beforeSend Function 请求发送前的hook,开发者可在发送前自行处理数据
reportCGI函数参数说明
参数名 类型 说明
name String 调用的接口名字,可在request接口的report字段配置
startTime Int 发起请求时的时间戳
endTime Int 请求返回时的时间戳
request Function 请求方法,可用于上报
beforeSend函数参数说明
参数名 类型 说明
obj Object 请求对象,包含url,data,header,开发者可自行修改,并最后将obj对象返回
code String wx.login()返回的用户登录凭证(有效期五分钟),用于初始登录,开发者可按需放入obj中
session String 登录态票据,开发者可按需将票据放入obj中
getSession函数参数说明
参数名 类型 说明
res string/Object/Arraybuffer 请求返回的数据
rawRes Object wx.request返回的response原始对象,内含header等信息。(注意:由于wx.uploadFile接口返回内容不支持header,故不建议将登录态放在header内返回)
errorCallback函数参数说明
参数名 类型 说明
obj Object 请求对象,包含url,data,header等内容
res Object 请求返回的错误信息,包含errMsg等信息

示例代码

weRequest.init({
    // [可选] 存在localStorage的session名称,且CGI请求的data中会自动带上以此为名称的session值;可不配置,默认为session
    sessionName: "session",
    // [可选] 存放code的名称;可不配置,默认值为code
    codeName: "js_code",
    // [可选] 请求URL的固定前缀;可不配置,默认为空
    urlPerfix: "https://www.example.com/",
    // [必填] 触发重新登录的条件,res为CGI返回的数据
    loginTrigger: function (res) {
        // 此处例子:当返回数据中的字段errcode等于-1,会自动触发重新登录
        return res.errcode == -1;
    },
    // [必填] 后端在接口中返回登录成功后的第三方登录态
    getSession: function(res, rawRes) {
        return res.session_id;
        // 若session返回在请求的header中
        // return rawRes.header.session_id;
    },
    // [可选] 登录重试次数,当连续请求登录接口返回失败次数超过这个次数,将不再重试登录;可不配置,默认为重试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。url为调用weRequest.request()时的url。mock数据的格式与正式接口提供的数据格式一致。
    mockJson: {
        url1: require("../../mock1.json"),
        url2: require("../../mock2.json"),
        url3: require("../../mock3.json")
    },
    // [可选] 所有请求都会自动带上globalData里的参数
    globalData: function() {
        return {
            version: getApp().version
        }
    },
    // [可选] session本地缓存时间(单位为ms),可不配置,默认不设置本地缓存时间
    sessionExpireTime: 24 * 60 * 60 * 1000,
    // [可选] session本地缓存时间存在Storage中的名字,可不配置,默认为 sessionExpireKey
    sessionExpireKey: "sessionExpireKey"
})

.request(OBJECT)

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

OBJECT参数说明

参数名 类型 必填 默认值 说明 是否与wx.request不一致
url String 开发者服务器接口地址,若在init()时有配置urlPerfix,则这里会自动拼接前缀
data Object/String 请求的参数
header Object 设置请求的 header,header 中不能设置 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/String false 请求过程页面是否展示全屏的loading,当值为字符串时,将展示相关文案的loading
report String 接口请求成功后将自动执行init()中配置的reportCGI函数,其中的name字段值为这里配置的值
cache Boolean 接口是否启用缓存机制,若为true,将以url为key将结果存储在storage中,下次带cache的请求优先返回缓存内容,success回调中第二个参数对象的isCache值将标识内容是否为缓存
noCacheFlash Boolean 当启用缓存时,决定除了返回缓存内容外,是否还返回接口实时内容,以防止页面多次渲染的抖动
catchError Boolean false 当使用Promise模式时,开发者是否需要捕获错误(默认不捕获,统一自动处理错误)

示例代码

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

.uploadFile(Object)

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

OBJECT参数说明

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

.getSession()

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

.getConfig()

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

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

.setSession(String)

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

.version

获取 weRequest 版本号

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函数,且默认错误弹框将不会出现。

当配置 catchError: true 并触发请求失败时,我能捕获到哪些信息?

当使用 Proimse 模式,并且开发者希望手动捕获错误时,就可以配置 catchError: true。此时触发请求失败时,就会抛出一个对象,里面包含了错误信息 msg(已通过配置的 errorContent 处理)和该请求最原始的返回包体 data。你可以通过 msg 直接用于上报或提示,也可以通过 data 来进行特殊的判断处理。

weRequest.request({
    url: 'order/detail',
    showLoading: true,
    data: { id: '123' }
}).then(res => {
    // 请求成功返回的数据 res
}).catch(e => {
    console.log(e.message); // 错误信息,已通过 `errorContent` 处理
    console.log(e.data); // 错误请求返回包体
})

业务登录态票据希望放在header里,需要怎么办?

可在调用init方法时,在钩子beforeSend中实现,举例如下:

weRequest.init({
    // ...
    beforeSend(obj, code, session) {
        if (code) {
            obj.header.code = code;
        } else if (session) {
            obj.header.session = session;
        }
        // 切记修改完后,需要将obj返回
        return obj;
    },
    // ...
})