前端基于uniapp完善的请求封装适用于(微信小程序,vue,管理后台,uniapp)
发布时间: 2023-05-08 17:15:24
作者: 王乐园 浏览次数:
553
以上代码是使用uni-app框架封装的一个通用请求方法 request() 。它包含了请求拦截器、响应拦截器、请求重试、加密/解密、缓存、文件上传等功能。
代码如下:
import cryptoJS from '@/utils/crypto-js.min.js'
const BASE_URL = 'http://example.com/api/';
let requestCount = 0;
const DEFAULT_OPTIONS = {
url: '',
method: 'GET',
data: {},
header: {
'content-type': 'application/json'
},
timeout: 10000, // 请求超时时间,单位毫秒
retry: 0, // 请求重试次数
encrypt: false, // 是否加密
cache: false, // 是否缓存
cacheTime: 60000, // 缓存时间,单位毫秒
cancelToken: null // 取消请求的 token
};
export default function request(options = {}) {
options = Object.assign({}, DEFAULT_OPTIONS, options);
// 请求次数加1
requestCount++;
// 请求拦截器
uni.showLoading({
title: '加载中'
});
return new Promise((resolve, reject) => {
let retryCount = 0;
const doRequest = () => {
// 取消请求
if (options.cancelToken) {
options.cancelToken.promise.then(cancel => {
reject(cancel);
});
}
const requestParams = {
url: BASE_URL + options.url,
method: options.method,
data: options.data,
header: options.header
};
// 加密处理
if (options.encrypt) {
const timestamp = Date.now();
const key = 'example'; // 加密的秘钥
const plainText = JSON.stringify(requestParams.data) + timestamp;
const cipherText = cryptoJS.AES.encrypt(plainText, key).toString();
requestParams.data = {
data: cipherText,
timestamp
};
}
// 缓存处理
if (options.cache) {
const cacheKey = options.url + JSON.stringify(requestParams.data);
const cachedData = uni.getStorageSync(cacheKey);
if (cachedData && Date.now() - cachedData.timestamp < options.cacheTime) {
resolve(cachedData.data);
return;
}
}
// 文件上传处理
if (options.files) {
requestParams.formData = options.data;
for (let i = 0; i < options.files.length; i++) {
const file = options.files[i];
requestParams.filePath = file.path;
requestParams.name = file.name;
}
}
uni.request({
...requestParams,
success: res => {
// 响应拦截器
uni.hideLoading();
if (res.statusCode === 200) {
// 解密处理
let data = res.data;
if (options.encrypt) {
const key = 'example'; // 解密的秘钥
const decryptedData = cryptoJS.AES.decrypt(data.data, key);
data = JSON.parse(decryptedData.toString(cryptoJS.enc.Utf8));
}
// 缓存处理
if (options.cache) {
const cacheKey = options.url + JSON.stringify(requestParams.data);
uni.setStorageSync(cacheKey, {
data,
timestamp: Date.now()
});
}
resolve(data);
} else {
reject(new Error(res.statusCode));
}
},
fail: err => {
// 错误处理
uni.hideLoading();
if (retryCount < options.retry) {
retryCount++;
doRequest();
} else {
reject(err);
}
},
complete: () => {
// 请求次数减1
requestCount--;
// 当所有请求都完成时,关闭Loading
if (requestCount === 0) {
uni.hideLoading();
}
}
});
};
// 发起请求前调用请求拦截器
let interceptor = {
request: config => config,
response: res => res
};
if (typeof options.interceptor === 'function') {
interceptor = options.interceptor(interceptor);
}
const modifiedOptions = interceptor.request(options);
doRequest(modifiedOptions);
// 请求超时处理
setTimeout(() => {
if (requestCount > 0) {
uni.hideLoading();
reject(new Error('Request timeout'));
}
}, options.timeout);
})
.then(res => {
// 在响应成功后调用响应拦截器
let interceptor = {
request: config => config,
response: res => res
};
if (typeof options.interceptor === 'function') {
interceptor = options.interceptor(interceptor);
}
return interceptor.response(res);
});
}
// 取消请求的 token
export function createCancelToken() {
const source = {
token: null,
cancel: null,
promise: null
};
source.promise = new Promise((resolve, reject) => {
source.cancel = reject;
});
source.token = {
source,
cancel: source.cancel
};
return source.token;
}
// 请求示例
/*
1. 加密请求示例
import request from '@/utils/request';
request({
url: 'package/create',
method: 'POST',
data: {
name: 'test package',
description: 'This is a test package',
price: 10,
quantity: 100
},
encrypt: true, // 启用加密
}).then(res => {
console.log(res);
}).catch(err => {
console.error(err);
});
2. 带请求拦截器和响应拦截器的请求示例:
import request from '@/utils/request';
request({
url: 'package/create',
method: 'POST',
data: {
name: 'test package',
description: 'This is a test package',
price: 10,
quantity: 100
},
interceptor: function (interceptor) {
// 请求拦截器
interceptor.request = config => {
// 在这里可以修改请求参数,例如添加统一的token
config.data.token = 'your token';
return config;
};
// 响应拦截器
interceptor.response = res => {
// 在这里可以对响应数据进行处理,例如统一处理错误提示
if (res.code !== 200) {
console.error('请求错误:' + res.msg);
}
return res;
};
return interceptor;
}
}).then(res => {
console.log(res);
}).catch(err => {
console.error(err);
});
3. 文件上传示例:
import request from '@/utils/request';
request({
url: 'package/upload',
method: 'POST',
data: {
name: 'test package',
description: 'This is a test package',
price: 10,
quantity: 100
},
files: [
{
path: '/path/to/your/file', // 本地文件路径,可以通过uni.chooseImage()等方法获取
name: 'file' // 文件对应的key,后台接收的参数名
}
],
}).then(res => {
console.log(res);
}).catch(err => {
console.error(err);
});
4. createCancelToken() 方法的主要作用是生成一个可以用于取消请求的token。这个方法返回一个对象,其中包含一个 source 属性(包含promise和cancel方法)和一个 cancel 方法。当你需要取消一个请求时,可以调用这个 cancel 方法。
*/
上一篇:(转载)追忆过往青春
下一篇:(转载)时光悠悠 岁月无言