在微信小程序原生开发过程中发现 wx.request 没有请求响应拦截的功能,所有参照 axios 对 wx.request进行简单的封装
/*
* 请求方式的枚举
*/
export enum HttpMethod {
GET = "GET",
HEAD = "HEAD",
POST = "POST",
PUT = "PUT",
DELETE = "DELETE",
OPTIONS = "OPTIONS",
TRACE = "TRACE",
CONNECT = "CONNECT"
}
/*
* 请求入参消息
*/
class RequestMessage {
Api:string;
Param: any;
Method: HttpMethod;
Header: Object;
constructor(api:string,param:any,method:HttpMethod = HttpMethod.GET,header:any = null){
this.Api = api;
this.Param = param;
this.Method = method;
this.Header = header;
}
}
/**
* HttpClient 实例
*/
class HttpClient {
private RequestInterceptor: Function | undefined;
private ReponseInterceptor: Function | undefined;
private baseUrl: string;
constructor(baseUrl:string = ''){
this.baseUrl = baseUrl;
}
/** 请求拦截器 */
public UseRequestInterceptor(interceptor:(requestMessage: RequestMessage) => boolean): HttpClient {
this.RequestInterceptor = interceptor;
return this;
}
/** 响应拦截器 */
public UseReponseInterceptor(interceptor:(reponseMessage:any) => any): HttpClient {
this.ReponseInterceptor = interceptor;
return this;
}
/**
* 发起请求
* @param requestMessage 请求体
*/
private Request(requestMessage:RequestMessage){
var that = this;
return new Promise((resolve,reject) => {
if(that.RequestInterceptor && !that.RequestInterceptor(requestMessage))
return reject("取消请求");
wx.request({
url: `${that.baseUrl}${requestMessage.Api}`,
data:requestMessage.Param,
method: requestMessage.Method,
header:requestMessage.Header,
success(res) {
resolve && resolve(that.ReponseInterceptor && that.ReponseInterceptor(res));
},
fail(error){
reject && reject(error);
}
});
});
}
/**
* Get 请求
* @param api 接口
* @param param 入参
*/
public Get(api: string, param: any) {
return this.Request(new RequestMessage(api,param));
}
/**
* Head 请求
* @param api
* @param param
* @returns
*/
public Head(api: string, param: any){
return this.Request(new RequestMessage(api,param,HttpMethod.HEAD));
}
/**
* Post 请求
* @param api 接口
* @param param 入参
*/
public Post(api: string, param: any){
return this.Request(new RequestMessage(api,param,HttpMethod.POST));
}
/**
* Connect 请求
* @param api
* @param param
* @returns
*/
public Connect(api: string,param:any){
return this.Request(new RequestMessage(api,param,HttpMethod.CONNECT));
}
/**
* OPTIONS 请求
* @param api
* @param param
* @returns
*/
public Options(api: string,param:any){
return this.Request(new RequestMessage(api,param,HttpMethod.OPTIONS));
}
/**
* Delete 请求
* @param api 接口
* @param param 入参
*/
public Delete(api: string,param?: any){
return this.Request(new RequestMessage(api,param,HttpMethod.DELETE));
}
/**
* Put 请求
* @param api 接口
* @param param 入参
*/
public Put(api: string, param: any){
return this.Request(new RequestMessage(api,param,HttpMethod.PUT));
}
}
/** HttpClient工厂 */
export class HttpClientFactory{
public static Create(baseUrl:string = ''): HttpClient{
return new HttpClient(baseUrl);
}
}
以上就是对于 wx.request 的封装,但是还是有缺陷,同一个 HttpClient 实例对象的拦截器多次注册只有最后一次注册的会起作用。(如果有需要这里可以直接变更,将 RequestInterceptor | ReponseInterceptor 改成数组,注册的时候不断把拦截器push到数组中,在拦截器执行的时候依次执行拦截器,或者如果有权重可以先排序后依次执行)
使用
import { HttpClientFactory } from '@/utils/request';
import { StatusCode } from '@/enums/httpstatus-enum';
import * as StorageConst from '@/consts/storage-const';
export const client = HttpClientFactory.Create('http://127.0.0.1:5000/api/');
/*
* 注册请求拦截器
*/
client.UseRequestInterceptor(requestMessage => {
if(requestMessage.Api !== "auth/login"){
requestMessage.Header = {
"Authorization" : wx.getStorageSync(StorageConst.BearerToken)
};
}
return true;
});
/*
* 注册请求拦截器
*/
client.UseReponseInterceptor(reponseMessage => {
reponseMessage&&console.log(reponseMessage);
switch(reponseMessage.statusCode){
case StatusCode.StatusCode200Ok:
return reponseMessage.data;
case StatusCode.StatusCode401NotAuthorization:
wx.redirectTo({ url :'../auth/login/index'});
return;
case StatusCode.StatusCode404NotFound:
wx.showToast(reponseMessage.statusCode)
return;
default:
return "状态码异常";
}
});
// apis/i-auth-service.js 文件
import { client } from '@/utils/http-client';
import { LoginInput } from '@/api/i-auth-service';
import * as StorageConst from '@/consts/storage-const';
/**
* 登录
* @param options
*/
export function Login(options:LoginInput) {
client.Post('auth/login',options).then(res => {
wx.setStorageSync(StorageConst.BearerToken, `Bearer ${res.data}` );
console.log(res);
}).catch(reason => {
console.log(reason);
});
}