config.js文件是这样的
interface Config {
baseUrl: string;
}
const config: Config = {
baseUrl: 'http://qu.test/api/weapp'
};
export default config;
我们可以将api列表封装在api.js
文件中,代码如下:
// api.ts
import Request from './request';
const request = new Request();
export const productApi = {
// 获取产品列表
list: () => request.get(`/products`, { noToken: true }),
// 新增产品
create: (data: any) => request.post(`/products`, data),
// 修改产品
update: (id: number | string, data: any) => request.put(`/products/${id}`, data),
// 删除产品
delete: (id: number | string) => request.delete(`/products/${id}`)
};
export const userApi = {
//当前用户信息
me: () => request.get(`/user`),
// 用户登录
// login: (data: any) => request.post(`/login`, data, { noToken: true }),
// 获取用户信息
// userInfo: () => request.get(`/user/info`)
};
完整的request.js
文件代码如下:
//request.ts
import config from './config';
interface RequestOptions {
baseUrl?: string;
url: string;
data?: any;
header?: any;
method?: string;
noToken?: boolean;
}
class Request {
private config = {
baseUrl: config.baseUrl,
header: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
method: 'GET',
noToken: false
};
private isWxLogin = false; // 增加一个标志位,用来判断是否正在调用wxLogin方法
public async wxLogin(): Promise<void> {
// 如果已经在调用wxLogin方法,则不再重新调用
if (this.isWxLogin) {
return;
}
// 将标志位设为true
this.isWxLogin = true;
try {
// 调用微信登录接口,获取code
const { code } = await wx.login();
const systemInfo = wx.getSystemInfoSync();
const device_name = systemInfo.model;
// 向后端发送请求,获取token
const res = await this.request({
url: '/authorizations',
data: { code, device_name },
method: 'POST',
noToken: true
});
// 将token以及根据expire_in计算的过期时间expiredTime存入缓存
wx.setStorageSync('token', res.data.token);
wx.setStorageSync('expiredTime', new Date().getTime() + res.data.expire_in * 1000);
// 将标志位设为false
this.isWxLogin = false;
} catch (e) {
// 将标志位设为false
this.isWxLogin = false;
throw e;
}
}
public async request(options: RequestOptions): Promise<any> {
// 获取缓存中的token
let token = wx.getStorageSync('token');
// 判断token是否存在或是否过期
if (!token || this.isTokenExpired(token)) {
// 如果token不存在或已过期,则调用wxLogin方法重新获取token
await this.wxLogin();
// 重新获取token
token = wx.getStorageSync('token');
}
// 如果token存在,则在请求的header中设置token
// 如果options中指定了不需要token,则不设置token
if (token && !options.noToken) {
options.header = options.header || {};
options.header.Authorization = `Bearer ${token}`;
} else {
// 否则,删除Authorization字段
// delete options.header.Authorization;
options.header = {};
}
// 合并用户传入的配置和默认配置
options = Object.assign({}, this.config, options);
// 请求的url
const url = options.baseUrl + options.url;
console.log(url)
// 请求的参数
const data = options.data;
// 请求的header
const header = options.header;
// 请求的方法
const method = options.method;
// 返回一个Promise对象
return new Promise((resolve, reject) => {
wx.request({
url,
data,
header,
method: method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'TRACE' | 'CONNECT',
success: (res) => {
// 请求成功,如果响应中有错误信息,则拒绝Promise
if (typeof res.data === 'string') {
reject(new Error(res.data));
} else {
const data = typeof res.data === 'object' ? res.data : JSON.parse(res.data);
if (data.status === 'error') {
reject(new Error(data.message));
} else {
resolve(res);
}
}
},
fail: (err) => {
// 请求失败,拒绝Promise
reject(err);
}
});
});
}
private isTokenExpired(token: string): boolean {
// 获取缓存中存储的 token 的过期时间
const expiredTime = wx.getStorageSync('expiredTime');
// 如果 expiredTime 不存在,则说明 token 不存在或已过期
if (!expiredTime) {
return true;
}
// 如果当前时间已经大于 expiredTime,则说明 token 已过期
if (new Date().getTime() > expiredTime) {
return true;
}
// 如果执行到这里,说明 token 未过期
return false;
}
public get(url: string, data?: any): Promise<any> {
return this.request({ url, data });
}
public post(url: string, data?: any): Promise<any> {
return this.request({ url, data, method: 'POST' });
}
public put(url: string, data?: any): Promise<any> {
return this.request({ url, data, method: 'PUT' });
}
public delete(url: string, data?: any): Promise<any> {
return this.request({ url, data, method: 'DELETE' });
}
}
export default Request;
在另一个页面中,您可以这样使用封装的API请求:
// 调用api接口
import { productApi, userApi } from './api';
// 获取产品列表,不携带token
const productList = await productApi.list();
console.log(productList);
// 新增产品,携带token
const addProduct = await productApi.create({ name: 'product1' });
console.log(addProduct);
// 修改产品,携带token
const updateProduct = await productApi.update(1, { name: 'product2' });
console.log(updateProduct);
// 删除产品,携带token
const deleteProduct = await productApi.delete(1);
console.log(deleteProduct);
// 用户登录,不携带token
const login = await userApi.login({ username: 'test', password: '123456' });
console.log(login);
// 获取用户信息,携带token
const userInfo = await userApi.userInfo();
console.log(userInfo);
// ...
// 调用其他模块的api接口
也可以根据状态码判断执行内容
const productList = await productApi.list();
if (productList.code === 200001) {
// 执行下一步操作
} else {
// 执行其他操作
}