文章目录
-
- [Vue 项目中下载返回的文件流操作步骤](#Vue 项目中下载返回的文件流操作步骤)
- [一、使用 Axios 请求文件流数据](#一、使用 Axios 请求文件流数据)
- [二、设置响应类型为 'blob'](#二、设置响应类型为 ‘blob’)
- 三、创建下载链接并触发下载
- [四、在 Vue 组件中集成下载功能](#四、在 Vue 组件中集成下载功能)
- 五、解释与实例说明
-
- [1、使用 Axios 请求文件流数据:](#1、使用 Axios 请求文件流数据:)
- [设置响应类型为 'blob':](#设置响应类型为 'blob':)
- 创建下载链接并触发下载:
- 下载文件,文件名获取不到
Vue 项目中下载返回的文件流操作步骤
1、使用 Axios 请求文件流数据;
2、设置响应类型为 'blob';
3、创建下载链接并触发下载。
其中,最关键的一步是创建一个 Blob 对象并使用 URL.createObjectURL 方法生成一个下载链接。以下将详细说明如何实现。
一、使用 Axios 请求文件流数据
在 Vue 项目中,需要使用 Axios 来发送请求并获取文件流数据。可以在组件中使用 Axios 进行 HTTP 请求,确保在请求头中设置适当的响应类型。
import axios from 'axios';
export default {
methods: {
downloadFile() {
axios({
method: 'get',
url: 'your-file-endpoint', // 替换为实际的文件流接口
params:{},
responseType: 'blob'
})
.then(response => {
this.handleFileDownload(response.data);
})
.catch(error => {
console.error('Error downloading the file', error);
});
}
}
};
二、设置响应类型为 'blob'
在 Axios 请求中,设置 responseType 为 'blob',这样 Axios 会将响应数据处理为 Blob 对象。Blob 对象表示一个不可变的、原始数据的类文件对象。
三、创建下载链接并触发下载
为了触发文件下载,需要创建一个 URL 链接并模拟点击事件。可以在组件中添加一个方法来处理 Blob 数据并进行下载。
methods: {
/**
* 拿到文件流后的下载的方法
* @param {*} data
* @param {*} filename
* @param {*} mime
* @param {*} bom
*/
function downloadByData(data: BlobPart, filename: string, mime?: string, bom?: BlobPart) {
const blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, filename);
} else {
const blobURL = window.URL.createObjectURL(blob);
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
tempLink.href = blobURL;
tempLink.setAttribute('download', filename);
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank');
}
document.body.appendChild(tempLink);
tempLink.click();
// 移除 a 标签
document.body.removeChild(tempLink);
// 释放 URL 对象
window.URL.revokeObjectURL(blobURL);
}
}
}
四、在 Vue 组件中集成下载功能
<template>
<div>
<button @click="downloadFile">Download File</button>
</div>
</template>
<script lang="ts" setup>
// 下载
async function downloadFile() {
try {
axios({
method: 'get',
url: 'your-file-endpoint', // 替换为实际的文件流接口
params: {}, // 请求参数
responseType: 'blob'
}).then(
(response) => {
console.log('downloadByData',response)
if(response.headers['content-disposition']) {
let fileName = response.headers['content-disposition'].split('filename=')[1];
// console.log('filename',fileName)
fileName = fileName.replace(/"/g, '');
downloadByData(response.data,fileName)
} else {
downloadByData(response.data,'xiazai.xlsx')
}
}
)
} catch (e) {
console.log(e);
}
}
/**
* 拿到文件流后的下载的方法
* @param {*} data
* @param {*} filename
* @param {*} mime
* @param {*} bom
*/
function downloadByData(data: BlobPart, filename: string, mime?: string, bom?: BlobPart) {
const blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, filename);
} else {
const blobURL = window.URL.createObjectURL(blob);
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
tempLink.href = blobURL;
tempLink.setAttribute('download', filename);
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank');
}
document.body.appendChild(tempLink);
tempLink.click();
document.body.removeChild(tempLink);
window.URL.revokeObjectURL(blobURL);
}
}
</script>
五、解释与实例说明
1、使用 Axios 请求文件流数据:
Axios 是一个基于 Promise 的 HTTP 客户端,可以用于浏览器和 Node.js。
在发送请求时,通过设置 responseType 为 'blob' 来确保返回的数据是二进制流格式。
设置响应类型为 'blob':
Blob 对象表示一个不可变的、原始数据的类文件对象,可以表示数据,比如二进制数据。
在请求中指定 responseType 为 'blob',可以确保 Axios 将响应数据处理为 Blob 对象。
创建下载链接并触发下载:
Blob 对象可以通过 URL.createObjectURL 方法生成一个临时的 URL,用于表示该 Blob 对象。
创建一个 a 标签,并设置其 href 属性为生成的 URL,download 属性为文件名。
通过 JavaScript 触发点击事件来启动下载,然后移除 a 标签并释放生成的 URL。
下载文件,文件名获取不到
二进制流下载文件,从response header里面获取文件名,后端也设置了header【Content-Disposition】的值为【attachment;filename=MY_DOCUMENT_23.pdf】
network查看请求,response header的确是有值,但是axios获取header的值,永远只有content-type
这个请求是跨域请求
服务端加一个额外的响应头
【Access-Control-Expose-Headers】值为【Content-Disposition】
设置了这个响应头后,axios就可以获取到content-disposition响应头,也就能够拿到这个附件名字