Nestjs教程文件上传与下载功能实现
我正在学习NestJS的文件上传与下载功能,遇到几个问题想请教:
- 如何在NestJS中配置multer来处理文件上传?官方文档的示例不太清楚具体配置参数的作用。
- 文件上传后如何自定义存储路径和文件名?目前默认是保存在内存中,想改成保存到服务器指定目录。
- 实现文件下载功能时,如何设置正确的响应头让浏览器弹出下载对话框?特别是处理不同文件类型时。
- 有没有完整的代码示例展示从上传到下载的完整流程?包括前端form表单和后端接口的配合。
- 大文件上传时有什么优化方案?比如分片上传或进度条显示的实现。
3 回复
要在NestJS中实现文件上传和下载功能,可以按照以下步骤操作:
-
安装依赖:首先,你需要安装必要的模块。使用
[@nestjs](/user/nestjs)/common
、[@nestjs](/user/nestjs)/multer
(处理文件上传)和fs
(文件系统模块,用于文件下载)。 -
配置Multer:在你的模块中配置Multer,设置上传目录和文件名规则。例如:
import { Module } from '[@nestjs](/user/nestjs)/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import * as multer from 'multer'; const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/'); }, filename: function (req, file, cb) { cb(null, Date.now() + '-' + file.originalname); }, }); [@Module](/user/Module)({ imports: [], controllers: [AppController], providers: [AppService], }) export class AppModule {}
-
创建控制器:在控制器中定义上传和下载的路由。例如:
import { Controller, Post, UploadedFile, Res } from '[@nestjs](/user/nestjs)/common'; import { FileInterceptor } from '[@nestjs](/user/nestjs)/platform-express'; [@Controller](/user/Controller)('files') export class FilesController { @Post('upload') @UseInterceptors(FileInterceptor('file', { storage })) uploadFile(@UploadedFile() file) { return { filename: file.filename }; } @Get('download/:filename') downloadFile(@Res() res, @Param('filename') filename: string) { res.sendFile(filename, { root: 'uploads/' }); } }
-
测试功能:运行应用后,可以通过POST请求上传文件,GET请求下载文件。
这样就完成了基本的文件上传和下载功能。记得处理异常和清理上传目录中的旧文件以避免磁盘空间耗尽。
要实现文件上传和下载功能,首先安装@nestjs/common
、@nestjs/multer
以及multer
库。创建一个控制器处理上传和下载逻辑。
- 上传:配置Multer处理文件上传。在
main.ts
引入Multer模块并定义存储策略。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MulterModule } from '@nestjs/platform-express';
@Module({
imports: [
MulterModule.register({
storage: diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
cb(null, file.fieldname + '-' + uniqueSuffix + '.' + extname(file.originalname));
},
}),
}),
],
})
export class AppModule {}
- 控制器:编写上传和下载接口。
import { Controller, Post, UploadedFile, Res } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { Response } from 'express';
@Controller('files')
export class FilesController {
@Post('upload')
@FileInterceptor('file') // 处理文件字段名为file
async uploadFile(@UploadedFile() file, @Res() res: Response) {
if (!file) return res.status(400).send('No file uploaded');
return res.send({ message: 'File uploaded successfully', file });
}
@Get('download/:filename')
async downloadFile(@Res() res: Response, @Param('filename') filename: string) {
try {
return res.download(`./uploads/${filename}`);
} catch (err) {
return res.status(500).send({ message: 'Error downloading file' });
}
}
}
确保上传目录存在,运行项目后可测试上传与下载功能。
NestJS 文件上传与下载功能实现
文件上传实现
- 首先安装所需依赖:
npm install @nestjs/platform-express multer
npm install @types/multer -D
- 创建一个文件上传模块:
import { Module } from '@nestjs/common';
import { FileController } from './file.controller';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';
@Module({
imports: [
MulterModule.register({
storage: diskStorage({
destination: './uploads',
filename: (req, file, callback) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
const ext = extname(file.originalname);
const filename = `${uniqueSuffix}${ext}`;
callback(null, filename);
},
}),
}),
],
controllers: [FileController],
})
export class FileModule {}
- 创建文件上传控制器:
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
@Controller('file')
export class FileController {
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
return {
originalname: file.originalname,
filename: file.filename,
size: file.size,
mimetype: file.mimetype,
};
}
}
文件下载实现
- 在文件控制器中添加下载方法:
import { Controller, Get, Param, Res } from '@nestjs/common';
import { Response } from 'express';
import * as fs from 'fs';
import * as path from 'path';
@Controller('file')
export class FileController {
// ...之前的uploadFile方法...
@Get('download/:filename')
downloadFile(@Param('filename') filename: string, @Res() res: Response) {
const filePath = path.join(__dirname, '../../uploads', filename);
if (fs.existsSync(filePath)) {
res.download(filePath, filename);
} else {
res.status(404).send('File not found');
}
}
}
注意事项
-
确保你的应用有写入
./uploads
目录的权限 -
在生产环境中,建议:
- 将上传文件存储在云存储服务中
- 添加文件类型和大小限制
- 实现文件清理机制
- 考虑安全因素,如防止恶意文件上传
-
前端调用示例:
// 上传文件
const formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch('/api/file/upload', {
method: 'POST',
body: formData
});
// 下载文件
window.open('/api/file/download/filename.ext');