javascript - NestJS Multer Amazon S3 上传多个文件时出现问题
问题描述
我在后端使用 NestJS、Node 和 Express,在前端使用 Angular。我有一个步进器,用户可以在其中逐步输入有关他们自己的信息以及个人资料照片和他们想要发布的任何艺术照片(这是一个草稿)。我正在使用以下代码将文件发送到后端:
<h2>Upload Some Photos</h2>
<label for="singleFile">Upload file</label>
<input id="singleFile" type="file" [fileUploadInputFor]= "fileUploadQueue"/>
<br>
<mat-file-upload-queue #fileUploadQueue
[fileAlias]="'file'"
[httpUrl]="'http://localhost:3000/profile/artPhotos'">
<mat-file-upload [file]="file" [id]="i" *ngFor="let file of fileUploadQueue.files; let i = index"></mat-file-upload>
</mat-file-upload-queue>
前端将照片作为文件数组发送;我试图改变它,让它只发送一个文件,但无法让它工作。我不太关注这一点,因为用户可能需要上传多个文件,所以无论如何我都想弄清楚。在后端,我使用 multer、multer-s3 和 AWS-SDK 来帮助上传文件,但它不起作用。这是控制器代码:
@Post('/artPhotos')
@UseInterceptors(FilesInterceptor('file'))
async uploadArtPhotos(@Req() req, @Res() res): Promise<void> {
req.file = req.files[0];
delete req.files;
// tslint:disable-next-line:no-console
console.log(req);
await this._profileService.fileupload(req, res);
}
这是配置文件服务:
import { Profile } from './profile.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ProfileDto } from './dto/profile.dto';
import { Req, Res, Injectable, UploadedFile } from '@nestjs/common';
import * as multer from 'multer';
import * as AWS from 'aws-sdk';
import * as multerS3 from 'multer-s3';
const AWS_S3_BUCKET_NAME = 'blah';
const s3 = new AWS.S3();
AWS.config.update({
accessKeyId: 'blah',
secretAccessKey: 'blah',
});
@Injectable()
export class ProfileService {
constructor(@InjectRepository(Profile)
private readonly profileRepository: Repository<Profile> ){}
async createProfile( profileDto: ProfileDto ): Promise<void> {
await this.profileRepository.save(profileDto);
}
async fileupload(@Req() req, @Res() res): Promise<void> {
try {
this.upload(req, res, error => {
if (error) {
// tslint:disable-next-line:no-console
console.log(error);
return res.status(404).json(`Failed to upload image file: ${error}`);
}
// tslint:disable-next-line:no-console
console.log('error');
return res.status(201).json(req.file);
});
} catch (error) {
// tslint:disable-next-line:no-console
console.log(error);
return res.status(500).json(`Failed to upload image file: ${error}`);
}
}
upload = multer({
storage: multerS3({
// tslint:disable-next-line:object-literal-shorthand
s3: s3,
bucket: AWS_S3_BUCKET_NAME,
acl: 'public-read',
// tslint:disable-next-line:object-literal-shorthand
key: (req, file, cb) => {
cb(null, `${Date.now().toString()} - ${file.originalname}`);
},
}),
}).array('upload', 1);
}
我还没有实现任何扩展 multer 的中间件,但我认为我不必这样做。您可以在控制器中看到我删除了 req 上的 files 属性并将其替换为文件,其中它的值只是 files 数组的第一个成员,但这只是为了看看如果我发送它所期望的东西它是否会工作,但当时没有用。有人对我如何解决这个问题有任何想法吗?或者任何人至少可以通过相关教程或其他内容的链接为我指明正确的方向?
解决方案
我的第一个猜测是您正在使用 FileInterceptor 和 multer。我假设 FileInterceptor 在控制器中添加了 multer 使其可用于@UploadedFile
装饰器。这可能会导致您以后使用 multer 发生冲突。尝试删除拦截器,看看是否能解决问题。
我还附上了我如何进行文件上传。我只上传单个图像并且我使用的是 AWS 开发工具包,因此我不必直接使用 multer,但这是我的做法,它可能会有所帮助。
在控制器中:
@Post(':id/uploadImage')
@UseInterceptors(FileInterceptor('file'))
public uploadImage(@Param() params: any, @UploadedFile() file: any): Promise<Property> {
return this.propertyService.addImage(params.id, file);
}
然后我的服务
/**
* Returns a promise with the URL string.
*
* @param file
*/
public uploadImage(file: any, urlKey: string): Promise<string> {
const params = {
Body: file.buffer,
Bucket: this.AWS_S3_BUCKET_NAME,
Key: urlKey
};
return this.s3
.putObject(params)
.promise()
.then(
data => {
return urlKey;
},
err => {
return err;
}
);
}
推荐阅读
- java - AndroidViewModel 没有零参数构造函数。如何解决这个问题?
- git - 版本控制并与 pdf 合并;不断更新的注释
- macos - 更新到 macOS Big Sur 后 XAMPP 不起作用
- python - 在 Tkinter 中更新或“刷新”帧
- html - 如何在 CSS 中为具有透明度的背景图像添加色调
- laravel - 如何使用 livewire 重置文件输入
- php - “foreach”循环中的不稳定值
- .net - 我的第二个应用程序池不起作用,('提供者:SQL 网络接口,错误:50 - 发生本地数据库运行时错误..)
- android - 如何在主屏幕上实现双击?(不在应用程序屏幕中)
- javascript - 在复选框更改时提交表单并保持内置浏览器验证