wx小程序对request请求进行简易的封装

     开发过程中,总喜欢对一些公共的方法进行一些特定的封装,以达到自己想要的效果,同时也可以使得代码简介、可维护、可复用,所以在自己实现一个wx小程序的时候特意对请求方式进行了封装,写的不好请别介意😐,喜欢可以点赞收藏

 1、本文采用的还是官方提供的uni.request方式,参考uni-app

参数名类型必填默认值说明平台差异说明
urlString开发者服务器接口地址
dataObject/String/ArrayBuffer请求的参数App 3.3.7 以下不支持 ArrayBuffer 类型
headerObject设置请求的 header,header 中不能设置 RefererApp、H5端会自动带上cookie,且H5端不可手动修改
methodStringGET有效值详见下方说明
timeoutNumber60000超时时间,单位 msH5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
dataTypeStringjson如果设为 json,会对返回的数据进行一次 JSON.parse,非 json 不会进行 JSON.parse
responseTypeStringtext设置响应的数据类型。合法值:text、arraybuffer支付宝小程序不支持
sslVerifyBooleantrue验证 ssl 证书仅App安卓端支持(HBuilderX 2.3.3+),不支持离线打包
withCredentialsBooleanfalse跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
firstIpv4BooleanfalseDNS解析时优先使用ipv4仅 App-Android 支持 (HBuilderX 2.8.0+)
enableHttp2Booleanfalse开启 http2微信小程序
enableQuicBooleanfalse开启 quic微信小程序
enableCacheBooleanfalse开启 cache微信小程序、抖音小程序 2.31.0+
enableHttpDNSBooleanfalse是否开启 HttpDNS 服务。如开启,需要同时填入 httpDNSServiceId 。 HttpDNS 用法详见 移动解析HttpDNS微信小程序
httpDNSServiceIdStringHttpDNS 服务商 Id。 HttpDNS 用法详见 移动解析HttpDNS微信小程序
enableChunkedBooleanfalse开启 transfer-encoding chunked微信小程序
forceCellularNetworkBooleanfalsewifi下使用移动网络发送请求微信小程序
enableCookieBooleanfalse开启后可在headers中编辑cookie支付宝小程序 10.2.33+
cloudCacheObject/Booleanfalse是否开启云加速(详见云加速服务百度小程序 3.310.11+
deferBooleanfalse控制当前请求是否延时至首屏内容渲染后发送百度小程序 3.310.11+
successFunction收到开发者服务器成功返回的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

2、首先我们可以先声明一个request类,在类的构造函数(constructor)中构建所需要的方法,对一些请求状态拦截,这个时候就可以使用api中addInterceptor进行拦截设置

参数名类型必填默认值说明平台差异说明
invokeFunction拦截前触发
returnValueFunction方法调用后触发,处理返回值
successFunction成功回调拦截
failFunction失败回调拦截
completeFunction完成回调拦截

代码部分

1、新建一个request.js文件

const baseURL = "https://example.com"

 uni.addInterceptor('request', {
            invoke(args) {
                // request 触发前拼接 url
                args.url = (args?.baseURL ? args?.baseURL : baseURL) + args.url;
                const token = uni.getStorageSync('user_token');
                if (token) {
                    args.header = {
                        ...args.header,
                        'Content-Type': 'application/json;charset=UTF-8',
                        Authorization: `${token}`,
                    }
                }
            },
            success(args) {
                // 请求成功后,修改code值为1
                // args.data.code = 200
            },
            fail(err) {
                console.log('interceptor-fail', err)
            },
            complete(res) {
            }
})

当对接口响应状态进行拦截的时候,我是放在了complete完成回调方法里面,这个里面可以获取同时获取到成功和失败的情况;所以要实现定义一个状态码提示

export const checkStatus = (status) => {
    let errorMessage = '';
    if (!status) return;
    switch (status) {
        case 401:
            errorMessage = '认证失败!';
            break;
        case 403:
            errorMessage = '请求被拒绝!';
            break;
        case 404:
            errorMessage = '请求不存在!';
            break;
        case 405:
            errorMessage = '请求方法不允许!';
            break;
        case 408:
            errorMessage = '请求超时!';
            break;
        case 500:
            errorMessage = '服务器错误!';
            break;
        case 501:
            errorMessage = '网络未实现!';
            break;
        case 502:
            errorMessage = '服务器无响应!';
            break;
        case 503:
            errorMessage = '服务器错误!';
            break;
        case 504:
            errorMessage = '网络超时!';
            break;
        default:
    }
    return errorMessage;
};

2、然后对接口的状态进行判断提醒

complete(res) {
                if (res.statusCode == 401) {
                    uni.showToast({
                        title: '认证失败',
                        icon: 'none',
                        duration: 2500,
                    })
                    uni.setStorageSync('user_token', null);
                    uni.setStorageSync('user_info', null);
                    
                    setTimeout(() => {
                        uni.reLaunch({
                            url: '/pages/login/login'
                        })
                    }, 500)
                } else if (res.statusCode != 200) {
                    uni.showToast({
                        title: checkStatus(res.statusCode) || res.statusCode || '接口网络异常',
                        icon: 'none',
                        duration: 2500,
                    })
                } else if (res.statusCode == 200) {
                    if (res.data.code != 200) {
                        if (res.data.code == 401) {
                            uni.showToast({
                                title: '认证失败',
                                icon: 'none',
                                duration: 2500,
                            })
                            uni.setStorageSync('user_token', null);
                            uni.setStorageSync('user_info', null);
                          
                            setTimeout(() => {
                                uni.reLaunch({
                                    url: '/pages/login/login'
                                })
                            }, 500)
                        } else if (checkStatus(res.data.code)) {
                            uni.showToast({
                                title: checkStatus(res.data.code) || '',
                                icon: 'none',
                                duration: 2500,
                            })
                        } else {
                            uni.showToast({
                                title: res.data.message || res.data.msg || '',
                                icon: 'none',
                                duration: 2500,
                            })
                        }
                    }
                }
                uni.hideLoading();
            }

到这里简易的拦截就做好了,这个时候就需要添加请求的方法,

request(config) {
        return new Promise((resolve, reject) => {
            uni.request({
                ...config,
                success: (res) => {
                    if (res.data.code == 200) {
                        resolve(res.data);
                    }
                   
                    reject(res.data.code)
                },
                fail(err) {
                    reject(err)
                }
            })
        })
    }

3、在请求的时候我们可能会习惯性的对请求方式进行分类,比如get、post、put、delete等方式,然后在项目的api中进行不同请求类型的调用,所以需要增加一个公共方法,以便能够在引入的时候能够使用不同的请求类型
首先封装一个httpRequest类,在类中对类型进行不同方法的封装,比如get请求方式

import Request from './request.js'

class httpRequest {
    constructor() {}

    get(url, data, config) {
        return this.request('GET', url, {
            data
        }, config);
    }

  
}


export default new httpRequest();

然后对request方法进行导入之前封装的Request请求类

import Request from './request.js'

class httpRequest {
    constructor() {}

    get(url, data, config) {
        return this.request('GET', url, {
            data
        }, config);
    }

    request(method, url, data, config) {
        return new Promise((resolve, reject) => {
            Request.request({ // 使用正确的 request 实例
                method,
                url,
                ...data,
                ...config
            }).then((resp) => {
                try {
                    resolve(resp);
                } catch (err) {
                    reject(err || new Error('request error!'));
                }
            }).catch((e) => {
                reject(e || new Error('request error!'));
            });
        })
    }
}


export default new httpRequest();

这个时候就配好了一个get请求方式,同时可以拿真实的接口进行验证,同时接口的域名需要在微信小程序中进行域名白名单的配置,否则调用的时候会没有权限。


完整代码

request.js文件

import {
    checkStatus
} from './checkStatus.js'

const baseURL = '' //基本URL地址

class Request {
    constructor(options) {
        uni.addInterceptor('request', {
            invoke(args) {
                // request 触发前拼接 url
                args.url = (args?.baseURL ? args?.baseURL : baseURL) + args.url;
                const token = uni.getStorageSync('user_token');
                if (token) {
                    args.header = {
                        ...args.header,
                        'Content-Type': 'application/json;charset=UTF-8',
                        Authorization: `${token}`,
                    }
                }
            },
            success(args) {
                // 请求成功后,修改code值为1
                // args.data.code = 200
            },
            fail(err) {
                console.log('interceptor-fail', err)
            },
            complete(res) {
                if (res.statusCode == 401) {
                    uni.showToast({
                        title: '认证失败',
                        icon: 'none',
                        duration: 2500,
                    })
                    uni.setStorageSync('user_token', null);
                    uni.setStorageSync('user_info', null);
                    setTimeout(() => {
                        uni.reLaunch({
                            url: '/pages/login/login'
                        })
                    }, 500)
                } else if (res.statusCode != 200) {
                    uni.showToast({
                        title: checkStatus(res.statusCode) || res.statusCode || '接口网络异常',
                        icon: 'none',
                        duration: 2500,
                    })
                } else if (res.statusCode == 200) {
                    if (res.data.code != 200) {
                        if (res.data.code == 401) {
                            uni.showToast({
                                title: '认证失败',
                                icon: 'none',
                                duration: 2500,
                            })
                            uni.setStorageSync('user_token', null);
                            uni.setStorageSync('user_info', null);
                            setTimeout(() => {
                                uni.reLaunch({
                                    url: '/pages/login/login'
                                })
                            }, 500)
                        } else if (checkStatus(res.data.code)) {
                            uni.showToast({
                                title: checkStatus(res.data.code) || '',
                                icon: 'none',
                                duration: 2500,
                            })
                        } else {
                            uni.showToast({
                                title: res.data.message || res.data.msg || '',
                                icon: 'none',
                                duration: 2500,
                            })
                        }
                    }
                }
                uni.hideLoading();
            }
        })
    }

    request(config) {
        return new Promise((resolve, reject) => {
            uni.request({
                ...config,
                success: (res) => {
                    if (res.data.code == 200) {
                        resolve(res.data);
                    }
                    if (config.isThrowError) {
                        resolve(res.data);
                    }
                    reject(res.data.code)
                },
                fail(err) {
                    reject(err)
                }
            })
        })
    }

}

export default new Request();

httpRequest.js文件

import Request from './request.js'

class httpRequest {
    constructor() {}

    get(url, data, config) {
        return this.request('GET', url, {
            data
        }, config);
    }

    post(url, data, config) {
        return this.request('POST', url, {
            data
        }, config);
    }

    put(url, data, config) {
        return this.request('PUT', url, {
            data
        }, config);
    }

    delete(url, data, config) {
        return this.request('DELETE', url, {
            data
        }, config);
    }

    request(method, url, data, config) {
        return new Promise((resolve, reject) => {
            Request.request({ // 使用正确的 request 实例
                method,
                url,
                ...data,
                ...config
            }).then((resp) => {
                try {
                    resolve(resp);
                } catch (err) {
                    reject(err || new Error('request error!'));
                }
            }).catch((e) => {
                reject(e || new Error('request error!'));
            });
        })
    }
}


export default new httpRequest();

checkStatus.js文件

export const checkStatus = (status) => {
    let errorMessage = '';
    if (!status) return;
    switch (status) {
        case 401:
            errorMessage = '认证失败!';
            break;
        case 403:
            errorMessage = '请求被拒绝!';
            break;
        case 404:
            errorMessage = '请求不存在!';
            break;
        case 405:
            errorMessage = '请求方法不允许!';
            break;
        case 408:
            errorMessage = '请求超时!';
            break;
        case 500:
            errorMessage = '服务器错误!';
            break;
        case 501:
            errorMessage = '网络未实现!';
            break;
        case 502:
            errorMessage = '服务器无响应!';
            break;
        case 503:
            errorMessage = '服务器错误!';
            break;
        case 504:
            errorMessage = '网络超时!';
            break;
        default:
    }
    return errorMessage;
};



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值