1、返回文件流(二进制数据)
这是最常用的导出方式 ------ 后端实时生成文件(如 Excel、PDF),不落地存储,直接以二进制流形式返回给前端,前端接收后解析为可下载的文件。
js
import axios from 'axios';
// 导出Excel接口请求
async function exportExcel() {
try {
const response = await axios({
method: 'GET', // 也可用POST(传筛选参数时用POST)
url: '/api/export/user-data', // 后端导出接口
params: { status: 'active' }, // 筛选参数(可选)
responseType: 'blob', // 关键:声明接收Blob二进制流
headers: { 'Authorization': 'Bearer ' + token } // 权限头(可选)
});
// 1. 从响应头提取文件名(处理中文编码)
const disposition = response.headers['content-disposition'];
let filename = '默认文件名.xlsx';
if (disposition) {
// 匹配 filename*=UTF-8''xxx 格式(RFC 5987标准,支持中文)
const match = disposition.match(/filename\*=UTF-8''([^;]+)/);
if (match && match[1]) {
filename = decodeURIComponent(match[1]); // 解码中文
}
}
// 2. 转换Blob为下载URL
const blob = new Blob([response.data], {
// 手动指定MIME类型(与后端Content-Type一致,避免识别错误)
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
const downloadUrl = URL.createObjectURL(blob);
// 3. 创建<a>标签触发下载
const a = document.createElement('a');
a.href = downloadUrl;
a.download = filename; // 文件名(浏览器会忽略URL中的文件名,以这个为准)
document.body.appendChild(a);
a.click(); // 模拟点击下载
// 4. 清理资源(避免内存泄漏)
document.body.removeChild(a);
URL.revokeObjectURL(downloadUrl); // 销毁临时URL
} catch (error) {
console.error('导出失败:', error);
// 特殊处理:若后端返回JSON错误(如参数错误),需解析Blob为JSON
if (error.response?.data instanceof Blob) {
const errorText = await new Response(error.response.data).text();
alert('导出失败:' + JSON.parse(errorText).message);
}
}
}
2、 文件下载链接(URL)
后端先将文件生成并存储在服务器 / 云存储(如 OSS、S3),再返回一个 临时有效的下载链接(含签名 / 过期时间,保证安全),前端直接通过链接触发下载。
js
async function getExportUrl() {
try {
const response = await axios.get('/api/export/get-download-url', {
params: { status: 'active' } // 筛选参数
});
const { downloadUrl, filename } = response.data.data;
// 方式1:用<a>标签下载(推荐,可指定文件名)
const a = document.createElement('a');
a.href = downloadUrl;
a.download = filename; // 强制指定文件名(若链接含文件名也可省略)
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
// 方式2:直接跳转(简单,但无法指定文件名,且可能触发浏览器预览)
// window.location.href = downloadUrl;
} catch (error) {
console.error('获取下载链接失败:', error);
}
}
//返回格式
{
"code": 200,
"message": "success",
"data": {
"downloadUrl": "https://xxx.com/files/export/user_123.xlsx?sign=abc123&expire=1717248000",
"filename": "用户数据.xlsx",
"expireTime": "2024-06-01 12:00:00"
}
}
3、 后端返回「Base64 编码字符串」
后端将文件转换为 Base64 字符串(二进制→ASCII 字符),嵌入 JSON 返回给前端,前端解码后转换为文件。仅适合小文件(如 100KB 以内,Base64 会比原文件大 30%,大文件会导致请求体过大)。
js
async function exportBase64File() {
try {
const response = await axios.get('/api/export/get-base64-file');
const { base64Str, filename } = response.data.data;
// 1. 解析Base64字符串(分离MIME类型和编码内容)
const [meta, base64Data] = base64Str.split(',');
const mime = meta.match(/:(.*?);/)[1]; // 提取MIME类型
// 2. Base64解码为二进制数据(Uint8Array)
const binaryStr = atob(base64Data); // atob解码Base64
const len = binaryStr.length;
const uint8Array = new Uint8Array(len);
for (let i = 0; i < len; i++) {
uint8Array[i] = binaryStr.charCodeAt(i); // 转换为二进制数组
}
// 3. 转换为Blob并下载(后续逻辑与文件流一致)
const blob = new Blob([uint8Array], { type: mime });
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
// 清理资源
document.body.removeChild(a);
URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error('导出失败:', error);
}
}
//返回格式
{
"code": 200,
"message": "success",
"data": {
"base64Str": "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,UEsDBBQABgAIAAAAIQ...",
"filename": "用户数据.xlsx"
}
}