作用:后端返回文件流,前端下载
前言
后端返回文件流,前端进行下载
提示:以下是本篇文章正文内容,下面案例可供参考
一、请求文件流:
函数接受两个参数:
url: 文件的 URL 地址。
fileName: 可选参数,指定下载文件的名称。
函数内部首先使用 Axios 发送一个 GET 请求到指定的 URL。
请求配置中包括:
设置响应类型为 blob,这使得 Axios 返回的数据会被解析为 Blob 对象,适合处理二进制数据如文件。
设置请求头中的 Content-Type 为 application/json,这通常用于发送 JSON 数据,但在这种情况下可能不需要,因为请求的是文件而非 JSON。
设置 Token 头,通常用于身份验证,getToken() 是一个假设存在的函数,用于获取当前用户的认证令牌。
二、处理响应
当请求成功后,从响应中获取以下信息:
responseType: 'blob' 意味着响应体是一个 Blob 对象。
response.headers['content-type'] 提供了文件的 MIME 类型,这有助于浏览器识别文件类型。
response.headers['content-disposition'] 包含了文件名信息,如果用户没有提供文件名,则尝试从这个头部中解析出文件名。
三、创建下载链接:
利用 DOM API 创建一个隐藏的 <a> 元素,并设置其 href 属性为 Blob 对象的 URL,这是通过调用 URL.createObjectURL() 方法得到的。同时,设置 download 属性为文件名,这告诉浏览器在点击链接时应下载文件而不是导航到新页面。
四、触发下载
触发下载: 将 <a> 元素添加到文档中,然后触发一个点击事件来开始下载过程。之后,移除 <a> 元素并释放 Blob URL 对象,避免内存泄漏。
五、代码示例
/**
* 使用Axios下载文件流
* @param {String} url - 请求的URL
* @param {String} [fileName] - 下载文件的名称,可选
*/
export async function downloadFileAsStream(url, fileName) {
try {
// 发起Axios请求,获取文件流
const response = await axios.get(process.env.VUE_APP_BASE_API + url, {
headers: {
'Content-Type': 'application/json',
'Token': getToken() // 添加token
},
responseType: 'blob', // 设置响应类型为blob
});
//响应数据
console.log("-----下载文件流-----", response)
// 获取文件类型,文件名称无需填写文件后缀,填写则会改变下载的文件类型
const contentType = response.headers['content-type'];
// 获取文件名,如果提供了文件名则使用,否则从响应头中获取
const contentDisposition = response.headers['content-disposition'];
if (!fileName && contentDisposition) {
const fileNameMatch = contentDisposition.match(/filename=(["'])(.*?)\1/);
if (fileNameMatch && fileNameMatch[2]) {
fileName = fileNameMatch[2];
}
}
//若是没有传入名称则拿去当前日期与时间作为文件名称
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const nowDate = `${year}-${month}-${day} ${hours}_${minutes}`;
// 创建一个链接元素用于下载
const link = document.createElement('a');
link.href = URL.createObjectURL(new Blob([response.data], { type: contentType }));
link.download = fileName || nowDate; // 设置下载文件的名称
// 将链接元素添加到DOM中并模拟点击
document.body.appendChild(link);
link.click();
// 移除链接元素并撤销URL对象
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} catch (error) {
// 处理错误
console.error('下载文件时发生错误:', error);
}
}