Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript NestJS Multer Amazon S3在上传多个文件时出现问题_Javascript_Node.js_Amazon S3_File Upload_Nestjs - Fatal编程技术网

Javascript NestJS Multer Amazon S3在上传多个文件时出现问题

Javascript NestJS Multer Amazon S3在上传多个文件时出现问题,javascript,node.js,amazon-s3,file-upload,nestjs,Javascript,Node.js,Amazon S3,File Upload,Nestjs,我的后端使用NestJS、Node和Express,前端使用Angular。我有一个步进器,用户可以在其中一步一步地输入关于自己的信息,以及一张个人资料照片和任何他们想发布的艺术照片(这是一个草稿)。我正在使用以下代码将文件发送到后端: <h2>Upload Some Photos</h2> <label for="singleFile">Upload file</label> <input id="singleFile" type="fi

我的后端使用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);
    }
@Post(“/artPhotos”)
@UseInterceptors(fileInterceptor('file'))
异步上传照片(@Req()Req,@Res()Res):承诺{
req.file=req.files[0];
删除请求文件;
//tslint:禁用下一行:无控制台
控制台日志(req);
等待此消息。_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);
}
从“/Profile.entity”导入{Profile};
从'@nestjs/typeorm'导入{InjectRepository};
从“typeorm”导入{Repository};
从“./dto/profile.dto”导入{ProfileDto};
从'@nestjs/common'导入{Req,Res,Injectable,UploadedFile};
从“multer”导入*作为multer;
从“AWS sdk”导入*作为AWS;
从“multer-s3”导入*作为multerS3;
const AWS_S3_BUCKET_NAME='blah';
const s3=新的AWS.s3();
AWS.config.update({
accessKeyId:'废话',
secretAccessKey:'废话',
});
@可注射()
导出类配置文件服务{
构造函数(@InjectRepository(概要文件)
专用只读配置文件存储库:存储库){}
异步createProfile(profileDto:profileDto):承诺{
等待这个.profileRepository.save(profileDto);
}
异步文件上传(@Req()Req,@Res()Res):承诺{
试一试{
上传(请求、回复、错误=>{
如果(错误){
//tslint:禁用下一行:无控制台
console.log(错误);
返回res.status(404.json)(`Failed to upload image file:${error}`);
}
//tslint:禁用下一行:无控制台
console.log('error');
返回res.status(201.json)(req.file);
});
}捕获(错误){
//tslint:禁用下一行:无控制台
console.log(错误);
返回res.status(500).json(`Failed to upload image file:${error}`);
}
}
上传=multer({
储存:multerS3({
//tslint:禁用下一行:对象文字速记
s3:s3,
桶:AWS_S3_桶名称,
acl:“公共读取”,
//tslint:禁用下一行:对象文字速记
密钥:(请求、文件、cb)=>{
cb(null,`${Date.now().toString()}-${file.originalname}`);
},
}),
}).array('upload',1);
}

我还没有实现任何中间件来扩展multer,但我认为我不必这么做。您可以在控制器中看到,我在req上擦除files属性,并将其替换为file,其中它的值只是files数组的第一个成员,但这只是为了查看如果我发送它期望的内容,它是否会工作,但它当时不工作。有人对我如何解决这个问题有什么想法吗?或者至少有人能给我指出一个正确的方向,并链接到相关的教程或其他东西吗?

我的第一个猜测是,您正在使用FileInterceptor和multer。我假设FileInterceptor在控制器中添加了multer,这使得
@UploadedFile
装饰器可以使用它。这可能会对您以后使用multer造成冲突。尝试删除拦截器,看看这是否解决了问题

此外,我附加我是如何做文件上传。我只上传单个图像,我使用的是AWS SDK,因此我不必直接与multer合作,但下面是我的做法,这可能会有所帮助

在控制器中:

  @Post(':id/uploadImage')
  @UseInterceptors(FileInterceptor('file'))
  public uploadImage(@Param() params: any, @UploadedFile() file: any): Promise<Property> {
    return this.propertyService.addImage(params.id, file);
}
@Post(':id/uploadImage')
@UseInterceptors(FileInterceptor('file'))
公共上载映像(@Param()params:any,@UploadedFile()file:any):承诺{
返回此.propertyService.addImage(params.id,文件);
}
然后我的服务

/**
 * 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;
      }
    );
}
/**
*返回带有URL字符串的承诺。
*
*@param文件
*/
公共上载映像(文件:any,urlKey:string):Promise{
常量参数={
正文:file.buffer,
Bucket:this.AWS_S3_Bucket_NAME,
密钥:urlKey
};
把这个还给我
.putObject(参数)
.承诺
.那么(
数据=>{
返回urlKey;
},
错误=>{
返回错误;
}
);
}

谢谢Jedediah,我喜欢你的代码这么简单。我复制了你的代码,但是仍然不起作用。事实证明,在使用accesskey和secretID更新配置后,您必须实例化s3对象。

您要传递给
uploadImage
函数的
urlKey是什么?urlKey是我希望文件在s3存储桶中的路径和名称。在我的例子中,我生成了一个UUID,与嵌套它的一些文件夹一起使用。因此,它可能类似于“users/2/0e7b55b7-1e4c-49c4-9a7e-93c526b7fb16”,它将位于“users”和“2”文件夹中,文件名为“0e7b55b7-1e4c-49c4-9a7e-93c526b7fb16”。您是否有更好地包含上载文件模块的要点?我和你有很多麻烦mine@DanutPralea我不能再多说了,但我确实总结了一个要点和一些细节。您介意将文件上传模块粘贴在这里或任何地方吗?我和你有着完全相同的问题,我花了无数个小时试图解决它。