微信小程序封装request请求,包含请求拦截器,响应拦截器和请求重试功能

这篇具有很好参考价值的文章主要介绍了微信小程序封装request请求,包含请求拦截器,响应拦截器和请求重试功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、需求:

  • 在发送请求之前,先判断用户是否有token,没有就执行登陆请求,将token保存,然后再执行原来请求;

  • 拥有token,就直接执行请求;但是用户的这个token可能是过期的,如果执行请求发现用户登陆过期,就统一返回40001,然后对40001的响应统一处理,执行登陆请求,再执行原来请求。

  • 最终实现用户无感登陆的体验效果。

二、流程图如下:

微信小程序请求拦截器,java专栏,微信小程序,微信小程序,小程序

三、主要代码

/**
 * 请求拦截器:
 * 在这里实现的作用是将所有请求前判断用户是否授权获取用户信息
 * @param {*} config 
 */
function requestInterceptor(config) {
    console.log("经过了请求拦截器")
    return new Promise((resolve, reject) => {
        if (!config.header.authorization) {
            userLogin().then(res =>{
                if(res){
                    config.header.authorization = wx.getStorageSync('userInfo').token
                    resolve(config);
                }
            })
        } else {
            resolve(config);
        }
    });
}
// 响应拦截器
function responseInterceptor(response) {
    console.log("经过响应拦截器")
    return new Promise((resolve, reject) => {
        // 处理响应结果
        if (response.data.flag) {
            resolve(response);
        } else {
            if (response.data.code === 40001) {
                userLogin().then(res => {
                    reject(response)
                })
            } else {
                wx.showToast({
                    title: response.data.message,
                    icon: "error",
                    duration: 2000
                })
            }
        }
    });
}

其中封装的一个post请求,带请求头

其他请求的封装方法完成类似,懂一个其他就都懂了。
微信小程序请求拦截器,java专栏,微信小程序,微信小程序,小程序

四、完整代码:

var tokenKey = "userInfo"; // 将登陆凭证储存以key为“token”储存在本地
var serverUrl = "http://localhost:8088/wechat"; // 2020

// 例外不用token的地址
// var exceptionAddrArr = ['/user/login', ];
var exceptionAddrArr = [];

//请求头处理函数
function CreateHeader(url, type) {
    let header = {}
    if (type == 'POST_PARAMS') {
        header = {
            'content-type': 'application/x-www-form-urlencoded'
        }
    } else {
        header = {
            'content-type': 'application/json'
        }
    }
    if (exceptionAddrArr.indexOf(url) == -1) { //排除请求的地址不须要token的地址
        let token = wx.getStorageSync(tokenKey).token;
        // header.Authorization = token;
        header['authorization'] = token;
    }
    return header;
}

/**
 * 请求拦截器:
 * 在这里实现的作用是将所有请求前判断用户是否授权获取用户信息
 * @param {*} config 
 */
function requestInterceptor(config) {
    console.log("经过了请求拦截器")
    return new Promise((resolve, reject) => {
        if (!config.header.authorization) {
            userLogin().then(res =>{
                if(res){
                    config.header.authorization = wx.getStorageSync('userInfo').token
                    resolve(config);
                }
            })
        } else {
            resolve(config);
        }
    });
}

// 响应拦截器
function responseInterceptor(response) {
    console.log("经过响应拦截器")
    return new Promise((resolve, reject) => {
        // 处理响应结果
        if (response.data.flag) {
            resolve(response);
        } else {
            if (response.data.code === 40001) {
                userLogin().then(res => {
                    reject(response)
                })
            } else {
                wx.showToast({
                    title: response.data.message,
                    icon: "error",
                    duration: 2000
                })
            }
        }
    });
}

/**
 * 封装wx.getUserProfile()方法
 */
function wxGetUserProfile() {
    return new Promise((resolve, reject) => {
        wx.getUserProfile({
            desc: '获取你的昵称、头像、地区及性别',
            success: (res) => {
                let userInfo = {
                    userName: res.userInfo.nickName,
                    iconUrl: res.userInfo.avatarUrl
                }
                wx.setStorageSync('userInfo', userInfo)
                resolve(userInfo)
            },
            fail: (res) => {
                reject(res)
            }
        })
    })
}

/**
 * 封装wx.login
 */
function wxLogin() {
    return new Promise((resolve, reject) => {
        wx.login({
            success: (res) => {
                console.log("wxLogin()获取验证码:" + res.code)
                resolve(res.code)
            },
            fail: (res) => {
                reject(res)
            }
        })
    })
}

/**
 * 封装后端登陆方法
 * @param {验证码} code 
 */
function mpLogin(data) {
    return new Promise((resolve, reject) => {
        wx.request({
            url: serverUrl + '/user/login',
            data: data,
            method: 'POST',
            success: (res => {
                resolve(res.data)
            }),
            fail: (res => {
                reject(res)
            }),
        })
    })
}

/**
 * 调用wx.login 和 mplogin 完成用户后端登陆
 */
async function userLogin() {
    let userInfo = wx.getStorageSync('userInfo');
    if (!userInfo) {
        userInfo = await wxGetUserProfile()
    }
    if(!userInfo){
        return;
    }
    let code = await wxLogin();
    let data = {
        code: code,
        userName: userInfo.userName,
        iconUrl: userInfo.iconUrl
    }
    return new Promise((resolve, reject) => {
        mpLogin(data).then(res => {
            if (res.flag) {
                console.log("userLogin()登陆成功返回信息:" + res)
                wx.setStorageSync('userInfo', res.data)
                resolve(true)
            } else {
                wx.showToast({
                    title: res.message,
                    icon: "error",
                    duration: 2000
                })
                resolve(false)
            }
        })
    })
}


//post请求,数据按照query方式传给后端
/**
 * 
 * @param {请求地址} url 
 * @param {请求数据} data 
 * @param {重试次数} times 
 */
function postRequest(url, data = {}, times) {
    // 获取请求头
    let header = CreateHeader(url, 'POST');
    return new Promise((resolve, reject) => {
        const config = {
            url: serverUrl + url,
            data: data,
            header:  header,
            method: 'POST',
            success: (res => {
                // 对响应统一处理
                responseInterceptor(res)
                    .then(res => {
                        resolve(res.data);
                    }).catch(res => {
                        // 重
                        if (times > 0) {
                            postRequest(url, data, times - 1).then(res => {
                                resolve(res)
                            })
                        } else {
                            wx.showToast({
                                title: '请稍后再试',
                                icon: "loading",
                            })
                        }
                    })
            }),
            fail: (res => {
                reject(res)
            }),
        }
        // 请求拦截器
        requestInterceptor(config)
            .then(config => {
                wx.request(config);
            }).catch(error => {
                reject(error);
            });
    })
}


//get 请求
function getRequest(url, data, times) {
    let header = CreateHeader(url, 'GET');
    return new Promise((resolve, reject) => {
        const config = {
            url: serverUrl + url,
            data: data,
            header: header,
            method: 'GET',
            success: (res => {
                responseInterceptor(res)
                    .then(res => {
                        resolve(res.data);
                    }).catch(res => {
                        // 重
                        if (times > 0) {
                            getRequest(url, data, times - 1).then(res => {
                                resolve(res)
                            })
                        } else {
                            wx.showToast({
                                title: '请稍后再试',
                                icon: "loading",
                            })
                        }
                    })
            }),
            fail: (res => {
                reject(res)
            })
        }
        // 请求拦截器
        requestInterceptor(config)
            .then(config => {
                wx.request(config);
            }).catch(error => {
                reject(error);
            });

    })
}
//put请求
function putRequest(url, data, times) {
    let header = CreateHeader(url, 'PUT');
    return new Promise((resolve, reject) => {
        const config = {
            url: serverUrl + url,
            data: data,
            header: header,
            method: 'PUT',
            success: (res => {
                responseInterceptor(res)
                    .then(res => {
                        resolve(res.data);
                    }).catch(res => {
                        // 重
                        if (times > 0) {
                            putRequest(url, data, times - 1).then(res =>{
                                resolve(res)
                            })
                        } else {
                            wx.showToast({
                                title: '请稍后再试',
                                icon: "loading",
                            })
                        }
                    })
            }),
            fail: (res => {
                reject(res)
            })
        }
    })
}
//delete请求
function deleteRequest(url, data, times) {
    let header = CreateHeader(url, 'DELETE');
    return new Promise((resolve, reject) => {
        const config = {
            url: serverUrl + url,
            data: data,
            header: header,
            method: 'DELETE',
            success: (res => {
                responseInterceptor(res)
                    .then(res => {
                        resolve(res.data);
                    }).catch(res => {
                        if (times > 0) {
                            deleteRequest(url, data, times - 1).then(res =>{
                                resolve(res)
                            })
                        } else {
                            wx.showToast({
                                title: '请稍后再试',
                                icon: "loading",
                            })
                        }
                    })
            }),
            fail: (res => {
                reject(res)
            })
        }
        // 请求拦截器
        requestInterceptor(config)
            .then(config => {
                wx.request(config);
            }).catch(error => {
                reject(error);
            });
    })
}



//导入
module.exports = {
    getRequest: getRequest,
    postRequest: postRequest,
    putRequest: putRequest,
    deleteRequest: deleteRequest,
    userLogin: userLogin,
}

五、使用示范:

const re = require('../../utils/request.js');	// 导入

Page({
  btCreateSubject(e){
      re.postRequest("/subject/create",{
          subjectName:"学习强国3"
      },2).then(res =>{
        console.log("创建科目成功返回数据:")
        console.log(res)
    })
  },
})
  • 在用户没有token的情况下:

    1. 进行请求拦截器,调用了登陆方法:
      微信小程序请求拦截器,java专栏,微信小程序,微信小程序,小程序
    2. 执行原来的操作,得到结果
      微信小程序请求拦截器,java专栏,微信小程序,微信小程序,小程序
  • 在用户有token的情况下,但是服务器已经没有维护用户的登陆状态了

    1. redis当中没有维护用户状态了
      微信小程序请求拦截器,java专栏,微信小程序,微信小程序,小程序

    2. 原本请求–>登陆请求–>原本请求
      微信小程序请求拦截器,java专栏,微信小程序,微信小程序,小程序

    3. 后端已经维持用户登陆状态
      微信小程序请求拦截器,java专栏,微信小程序,微信小程序,小程序文章来源地址https://www.toymoban.com/news/detail-649509.html

总结:

  • 虽然这样封装看起来挺复杂的,但是对于用户来说是一种很好的体验。对于普通的网站,如果发现你你的登陆过期,又得重新输入密码注册。但是这样我们无全不需要,只要你已经是登陆过的用户,除非你清除了小程序的缓存,否则在你接下来使用过程中都不需要再手机登陆。
  • 其次,对于前端js编写来说,不需要在每个请求前都去判断用户是否本地缓存有token,都在由请求拦截器统一处理。对于请求后的响应,我们不需要去处理各种情况,只需要处理成功的情况就可以了。

关于实现小程序用户“无感”登陆的方法,我相信这不是最优解,但是这是我目前能想到最好的解决办法了。如果小伙伴有更好的登陆流程,欢迎在评论区告诉我,一起讨论~

到了这里,关于微信小程序封装request请求,包含请求拦截器,响应拦截器和请求重试功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uniapp微信小程序封装网络请求 @escook/request-miniprogram

    官网地址:https://www.npmjs.com/package/@escook/request-miniprogram 1、下载依赖 2、引入 把下面代码放到 main.js 3、发起请求 4、请求成功 可以看到请求成功了,并执行了登入成功的逻辑。 每次发起请求后,都要自己写if语句判断请求是否成功,非常麻烦。我们可以修改一下源码解决这个

    2024年02月10日
    浏览(43)
  • uniapp 微信小程序 封装axios 包含请求拦截、响应拦截、无感刷新令牌功能

    前言: 1、为什么不适用uniapp自带的请求功能? 答:uniapp自带的请求功能,再刷新了令牌后,重新请求返回的数据无法返回给发起请求的方法。也就是说,刷新令牌后重新发起的请求和第一次发起请求的方法是割裂的。 2、封装文件中,我设置了无感刷新令牌功能。我后台的

    2024年02月03日
    浏览(62)
  • 【JWT】SpringBoot+微信小程序根据指定参数生成Token、更新Token、判断Token是否已经过期、封装wx.request请求更新Token并判断Token是否过期

    微信小程序js代码 微信小程序点击登录按钮调用该方法 java后端代码 getUserCode方法为获取用户的唯一标识openId userLogin方法用于用户授权登录并获取Token userLogin实现类方法 封装了wx的request请求,每次发起请求的时候都走一遍更新Token的接口/user/updateTokenTime,如果接口返回offlin

    2024年02月04日
    浏览(50)
  • 【uniapp&微信小程序】封装uni.request()

    前言         在项目开发过程中,往往需要对请求进行二次封装,这篇文章将对uni.request()进行二次封装,并实现多个环境的请求配置,对请求方式,数据格式等进行封装,将请求做到最简化。 一.封装uni.request() 第一步基于 uni.request() 进行二次封装,集成项目开发中需要的参

    2024年02月09日
    浏览(86)
  • 微信小程序封装请求

    封装请求 解决的问题 很多页面中请求的 url 前半部分都是一样的,重复书写导致页面代码冗余复杂同时逻辑容易不清晰,所以采用单独将请求封装成一个文件(模块)使得这些问题得到解决。 前期基础知识 uni.request(wx.request) Promise 具体步骤 创建文件夹及文件 在根目录下

    2024年02月11日
    浏览(43)
  • 微信小程序 基于Promise 对 wx.request 封装处理

    当我们进行微信小程序开发的时候,会经常涉及到发送网络请求来进行后台数据交互,而在微信小程序中,用来 发送请求的方法是 wx.request() , 但是由于 wx.request() 方法 不支持 Promise 风格的调用,所以导致 wx.request() 用来发送异步请求的时候,会触发成 回调地狱 的表现, 以及

    2024年02月04日
    浏览(45)
  • 微信小程序网络请求封装

    网络请求地址放到url.js中,分别制定开发环境,体验环境,线上环境 网络请求的方法放到request.js中,暴露get、post、wxLogin方法 请求前显示加载中,请求结束后隐藏加载中 请求的接口方法,放到api.js中,并调用request.js中对应的方法 2.1 请求地址(url.js) 2.3 具体的请求方法(api.

    2024年02月15日
    浏览(39)
  • 【小程序教程】微信小程序之request网络请求

    微信小程序提供了request网络请求的API,可以用于与后台服务器进行数据交互,实现数据的获取和提交等功能。在本文中,将介绍如何使用request网络请求API,并提供一个示例代码,帮助大家更好地理解。 使用request网络请求API的步骤如下: 在小程序页面中,需要在页面或者组

    2024年02月04日
    浏览(47)
  • 【微信小程序】使用 wx.request 方法进行异步网络请求

    在微信小程序中,你可以使用 wx.request 方法进行异步网络请求,并将获取到的列表数据渲染到 UI 上。 首先,在页面的 data 中定义一个数组变量,用于存储获取到的列表数据,例如: 然后,在页面的生命周期函数 onLoad 或需要触发网络请求的函数中,使用 wx.request 方法发送异

    2024年02月16日
    浏览(56)
  • 微信小程序基于Promise封装发起网络请求

         

    2024年02月17日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包