vue文件下载后端实现
后端实现文件下载
在Vue项目中实现文件下载功能通常需要后端配合,以下是常见的后端实现方式(以Node.js为例):
基于Express框架的实现
const express = require('express');
const fs = require('fs');
const path = require('path');
app.get('/download', (req, res) => {
const filePath = path.join(__dirname, 'files/sample.pdf');
const stat = fs.statSync(filePath);
res.setHeader('Content-Length', stat.size);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=sample.pdf');
const readStream = fs.createReadStream(filePath);
readStream.pipe(res);
});
Spring Boot实现
@GetMapping("/download")
public ResponseEntity<Resource> downloadFile() throws IOException {
Path filePath = Paths.get("files/sample.pdf");
Resource resource = new InputStreamResource(Files.newInputStream(filePath));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=sample.pdf")
.contentType(MediaType.APPLICATION_PDF)
.body(resource);
}
前端Vue调用方式
axios({
method: 'get',
url: '/download',
responseType: 'blob'
}).then(response => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'sample.pdf');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
处理大文件下载
对于大文件下载,建议使用分块传输:
app.get('/download-large', (req, res) => {
const filePath = path.join(__dirname, 'files/large-file.zip');
const stat = fs.statSync(filePath);
res.writeHead(200, {
'Content-Length': stat.size,
'Content-Type': 'application/zip',
'Content-Disposition': 'attachment; filename=large-file.zip'
});
const readStream = fs.createReadStream(filePath);
readStream.pipe(res);
});
安全注意事项
设置适当的权限检查:
app.get('/download-secure', authenticateUser, (req, res) => {
if (!req.user.hasPermission('download')) {
return res.status(403).send('Forbidden');
}
// 正常下载逻辑
});
性能优化技巧
使用流式传输避免内存压力:
app.get('/download-optimized', (req, res) => {
const filePath = path.join(__dirname, 'files/large-file.zip');
const readStream = fs.createReadStream(filePath);
res.setHeader('Content-Disposition', 'attachment; filename=large-file.zip');
readStream.pipe(res);
readStream.on('error', (err) => {
res.status(500).send('File transfer error');
});
});
常见问题解决
处理中文文件名乱码:
res.setHeader('Content-Disposition',
`attachment; filename*=UTF-8''${encodeURIComponent(filename)}`);
实现进度显示(前端):

axios({
method: 'get',
url: '/download',
responseType: 'blob',
onDownloadProgress: progressEvent => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(percentCompleted + '%');
}
})






