Vue3 中判断接口返回的是文件流还是 JSON 提示信息
需求:
前端上传一个Excel文件到后端,后端返回结果分以下两种情况:
- 返回的是可下载Excel文件,直接下载到本地
- 返回的是 JSON 格式的提示信息({ code: 200, message: “操作成功” })
实现代码
// 核心上传逻辑
const handleUpload = async (file) => {
isUploading.value = true;
message.value = '';
try {
const formData = new FormData();
formData.append('file', file);
const response = await axios.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
responseType: 'blob'
});
// 根据Content-Type区分响应类型
const contentType = response.headers['content-type'];
const data = response.data;// 关键配置
// 处理成功响应(JSON)
if (contentType.includes('application/json')) {
//解析blob中的信息
const reader = new FileReader();
reader.readAsText(data);
reader.onload = () => {
const result = JSON.parse(reader.result);
messageType.value = 'success';
message.value = `上传成功:${result.message}`;
ElMessage.success(result.message || '文件处理完成');
};
}
// 处理错误响应(Excel)
else if (contentType.includes('application/vnd.ms-excel')) {
handleErrorExcel(data);
messageType.value = 'error';
message.value = '存在错误数据,已生成错误文件';
ElMessage.error('请下载错误文件修改后重新上传');
}
} catch (error) {
// 处理网络/服务器错误
handleRequestError(error);
} finally {
isUploading.value = false;
}
};
// 处理错误Excel下载
const handleErrorExcel = (blobData) => {
// 创建可下载链接
const url = window.URL.createObjectURL(new Blob([blobData]));
const link = document.createElement('a');
link.href = url;
// 获取文件名(从Content-Disposition中提取)
const disposition = response.headers['content-disposition'];
let filename = 'default-filename';
if (disposition) {
const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
const matches = filenameRegex.exec(disposition);
if (matches?.[1]) {
filename = matches[1].replace(/['"]/g, '');
//从URL获取的编码参数
//filename =decodeURIComponent(matches[1].replace(/['"]/g, ''))
}
}
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
// 清理资源
document.body.removeChild(link);
URL.revokeObjectURL(url);
};