在我们的日常开发中,文件上传与下载一直都是比较常见的问题,为了统一开发者的书写和保障开发效率,这里对文件的上传下载做了如下封装
axios封装
import axios from "axios";
import { Message } from "element-ui";
const request = axios;
request.interceptors.request.use(
function (config) {
if (store.state.userInfo.access_token) {
config.headers["access_token"] = getToken();
}
return config;
},
function (error) {
return Promise.reject(error);
}
);
request.interceptors.response.use(
function (response) {
//文件下载处理
const headers = response.headers;
if (headers["content-type"] === "application/octet-stream") {
if (headers["content-disposition"]) {
sessionStorage.setItem(
"content-disposition",
headers["content-disposition"]
);
}
return response.data;
}
// 对响应数据做点什么
let data = response.data;
let { message, code } = data;
if (code !== 200) {
Message.error({
message: "系统异常",
});
return Promise.reject(response.data || "Error");
}
return data;
},
function (error) {
// 对响应错误做点什么
return Promise.reject(error);
}
);
export default request;
封装上传下载api
import request from "@/plugins/axios/request.js";
// 全局上传的请求函数(请不要操作)
export function upload(data, url, method = "post") {
return request({
url: url,
method: method,
data,
headers: { "Content-Type": "multipart/form-data" },
});
}
// 下载文件以流的形式
export function downloadStream(data, url, method = "get", isBlob = true) {
// 该列表中 url responseType 不为 blob
const urlWhiteList = [];
if (urlWhiteList.includes(url)) {
isBlob = false;
}
const temp = {
url: url,
};
if (isBlob) {
temp.responseType = "blob";
}
if (method === "post") {
temp.method = "post";
temp.data = data;
} else {
temp.method = "get";
temp.params = data;
}
return request(temp);
}
// 删除文件
export function deleteFile(data, url, method = "post") {
if (method === "post") {
return request({
url: url,
method: method,
data,
});
} else {
return request({
url: url,
method: method,
params: data,
});
}
}
封装下载公共方法
/**
* @description: 以流的形式下载文件
* @param: {Blob} 流文件
* @return {undefined}
* @author: zzl
*/
export function downloadFile(res, type = "pdf") {
if (res.data) {
const url = pathJoin(process.env.VUE_APP_BASE_API, res.data);
downloadForA(url);
} else {
// 兼容 ie
if (checkBrowser().includes("IE")) {
const blob = new Blob([res]);
window.navigator.msSaveOrOpenBlob(blob, `${res.fileName}.${type}`);
} else {
const blobUrl = window.URL.createObjectURL(new Blob([res]));
downloadForA(blobUrl);
}
}
}
function downloadForA(url) {
let temp =
sessionStorage.getItem("content-disposition") &&
sessionStorage.getItem("content-disposition").split("=");
temp = temp && temp[temp.length - 1];
// 进行解码获取文件名称
let fileName = decodeURI(temp);
const fileNameSplit = fileName.split(".");
if (fileNameSplit.length === 2 && fileNameSplit[0] === "") {
fileName = "file" + fileName;
}
const link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName);
// 模拟
document.body.appendChild(link);
link.click();
// 释放URL 对象
window.URL.revokeObjectURL(link.href);
document.body.removeChild(link);
}
前端具体使用
上传文件
import { upload } from "@/api/fileApi/index.js";
// 上传安装包
uploadFile(param) {
const formData = new FormData();
//表单可以添加文件和很多字段
formData.append("file", param.file);
formData.append("softwareId", this.currentId);
upload(
formData,
"你的接口地址",
"post"
)
.then((res) => {
const { code, data, message } = res;
if (code === 200) {
this.$message.success("上传成功");
}
})
.catch(() => {
this.$message.warning("上传失败");
});
},
下载文件
import { downloadStream } from "@/api/fileApi/index.js";
import { downloadFile } from "@/plugins/axios/fileHalder.js";
// 下载安装包 这里downloadStrea api和downloadFile公共方法结合使用
downloadPackage(id) {
downloadStream(
{ softwareId: id },
"你的下载地址",
"get"
).then((res) => {
downloadFile(res);
});
},
后端
后端以流的形式输出文件,
response.setHeader("content-type","application/octet-stream")
response.setHeader("content-disposition",fileName) //注意这里的文件名要UTF-8编码
response.outPutStream(fileStream) //输出文件流
response.outPutStream.close() //关闭流