今天跟后端一起设计了一个图片上传的流程:
将用户上传的图片信息通过formData数据发送给后端,后端存储后返回图片名给前端。前端调用函数,将图片名当做参数再次传递给后端,后端将图片的二进制流信息返回。前端将二进制流信息转为base64,展现在页面中,这样就完成了图片的上传,以及回显。
这里为什么要再次将图片名传递给后端呢,是因为我们不仅仅要完成图片的上传,还有图片信息的回显,当我们的数据中有图片名,就表示这个数据是用于回显的数据,就需要调用封装好的函数来实现图片的回显。
废话说完了,我们来回归标题中提到的怎么将二进制流文件转为base64编码
利用拦截器设置响应数据类型为arraybuffer
下面代码中我们根据请求的地址是否包含上传图片的地址,如果包含则需要给请求参数设置responseType为arraybuffer可以参考下面链接
👇👇👇👇👇👇👇👇
uni.request(OBJECT) | uni-app官网 (dcloud.net.cn)
function httpInterceptor(options) {
// 请求前的拦截器逻辑
const secretStore = userSecretStore();
// 判断非http开头需要拼接参数
if (!options.url.startsWith('http')) {
options.url = baseUrl + options.url;
}
if (options.url.includes('getIdCardImage')) options.responseType = 'arraybuffer'; // 如果请求地址是图片上传,则需要设置请求类型为arraybuffer
// 设置请求超时时间
if (!options['timeout']) options.timeout = 10000;
// 设置请求头
options.header = {
...options.header,
uniqueId: secretStore.uniqueid,
iv: secretStore.iv,
};
return options;
}
在响应拦截器中检查是否是二进制数据,并进行相应转换
success: (response) => {
// 响应拦截器逻辑
// 检查是否是二进制数据响应
if (response.data && response.data.constructor === ArrayBuffer) {
const base64Data = uni.arrayBufferToBase64(response.data);
response.data = 'data:image/png;base64,' + base64Data; // 如果是二进制流数据,则需要将二进制流数据转为bace64类型数据并回显
}
resolve(response.data); // 根据需要调整
},
这里使用到了uni.arrayBufferToBase64方法将 ArrayBuffer 对象转成 Base64 字符串
uni.arrayBufferToBase64(arrayBuffer) | uni-app官网 (dcloud.net.cn)
完整拦截器代码
const baseUrl = 'URL_ADDRESS';
function httpInterceptor(options) {
// 判断非http开头需要拼接参数
if (!options.url.startsWith('http')) {
options.url = baseUrl + options.url;
}
if (options.url.includes('getIdCardImage')) options.responseType = 'arraybuffer'; // 如果请求地址是图片上传,则需要设置请求类型为arraybuffer
// 设置请求超时时间
if (!options['timeout']) options.timeout = 10000;
// 设置请求头
options.header = {
...options.header,
// 可以自行添加数据
};
return options;
}
const request = (options) => {
options = httpInterceptor(options); // 在发送请求前调用拦截器
return new Promise((resolve, reject) => {
uni.request({
...options,
success: (response) => {
// 响应拦截器逻辑
// 检查是否是二进制数据响应
if (response.data && response.data.constructor === ArrayBuffer) {
const base64Data = uni.arrayBufferToBase64(response.data);
response.data = 'data:image/png;base64,' + base64Data; // 如果是二进制流数据,则需要将二进制流数据转为bace64类型数据并回显
}
resolve(response.data); // 根据需要调整
},
fail: (error) => {
if (error.errMsg.includes('timeout')) {
// 显示错误消息给用户
uni.showModal({
title: '网络错误',
content: '请求超时,请检查网络连接',
showCancel: false,
confirmColor: '#007AFF',
confirmText: '确定',
});
} else {
// 非超时错误处理
reject(error);
uni.showModal({
title: '请求失败',
content: '请求失败,请重新尝试',
showCancel: false,
confirmColor: '#007AFF',
confirmText: '确定',
});
}
},
});
});
};
export default request;