后端接口/**/export定义 content-type: application/octet-stream
前端:
-
headers 中需要加 headers['Content-Type'] = 'application/octet-stream';
-
前端在请求时必须要加上responseType, 否则 在下载下来的文件打开无法被解析
![](https://img-blog.csdnimg.cn/img_convert/326a13168da34e1447d2dbb05356ff77.png)
![](https://img-blog.csdnimg.cn/img_convert/7510f677aa8c72bdc1174b40a8c0f6f4.png)
config.responseType = 'blob';
1,2在axios 请求时加上可正常解析
![](https://img-blog.csdnimg.cn/img_convert/947eb961861fdc2a08865b69a1876ef1.png)
前端处理逻辑封装
export async function downloadFileMessage(response, data, fileName) {
// 如果响应体Body已经被使用过,那么clone()会抛出一个TypeError。实际上,clone() 的主要作用就是支持Body对象的多次使用
const blob = data?.blob ? await data.clone().blob() : new Blob([data]);
const a = document.createElement('a');
const downloadUrl = window.URL.createObjectURL(blob);
const contentDisposition = response.headers ? response.headers['content-disposition'] : `filename=${fileName}`;
if (contentDisposition) {
const name = contentDisposition.split('filename=')[1].replace(/"/g, '');
a.href = downloadUrl;
a.download = name || fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(downloadUrl);
return;
}
// 只能消费Response.json()一次,如果你消费不止一次,就会发生错误。TypeError: Failed to execute 'json' on 'Response': body stream already read
const jsonData = await data.clone().json();
if (jsonData && (jsonData?.status === '500' || jsonData?.status === 500)) {
message.error(jsonData?.message || '下载失败');
}
}
视频录制.h264文件
export const donwloadFile = (response, fileName) => {
const fileReader = new FileReader();
let name = fileName;
if (response.headers["content-disposition"]) {
name = decodeURI(
response.headers["content-disposition"]
.split(";")[1]
.split("filename=")[1]
);
}
fileReader.onload = () => {
const blob = new Blob([response.data], {
type: response?.data?.type,
});
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", name ?? fileName);
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
};
fileReader.readAsText(response.data);
};
使用
downloadVideoFile: async function (video, deviceId) {
try {
// 结束录制
await saveVideo({ video, deviceId, flag: 0 });
this.$message.success("结束录制");
this.recording = !this.recording;
try {
const response = await downloadVideo({
deviceId,
filename: this.filename,
});
const time = dayjs(new Date().getTime()).format(
"YYYY_MM_DD_HH_mm_ss"
);
const newName = `${name}_${time}.h264`;
await donwloadFile(response, newName);
this.$message.success("完成下载");
} catch (error) {
throw error;
}
} catch (error) {
throw error;
}
},