ค้นหาเว็บไซต์

javascript - nestjs multer รับรายการชื่อไฟล์ใหม่หลังจากการเก็บของ multer


ฉันมีมิดเดิลแวร์นี้ที่ฉันใช้ในการอัปโหลดไฟล์

@Injectable()
export class FilesMiddleware implements NestMiddleware {

  private storage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, path.join(__dirname, '../../uploads/'));
    },
    filename: (req, file, cb) => {
      let extArray = file.mimetype.split("/");
      let extension = extArray[extArray.length - 1];
      cb(null, file.fieldname + '-' + Date.now() + '.' + extension)
    }
});

  resolve(...args: any[]): MiddlewareFunction {
    return (req, res, next) => {
      console.log(req.files);
      const upload = multer({storage: this.storage});
      upload.any();
      return next();
    }
  }
}

ปัญหาคือในการร้องขอของฉัน เมื่อฉันใช้ req.files มันจะแสดงชื่อไฟล์ต้นฉบับแทนที่จะเป็นชื่อไฟล์ใหม่ (พร้อมวันที่ ฯลฯ ตามที่ฉันตั้งค่าในตัวเลือกการจัดเก็บของ multer)

มีวิธีที่ฉันจะได้ชื่อไฟล์ใหม่ที่ multer อัปโหลดโดยใช้มิดเดิลแวร์หรือไม่?

@Post('upload')
@UseInterceptors(FilesInterceptor('files[]', 20, {}))
public async onUpload(@Request() req, @Response() res, @UploadedFiles() files) {
    const mediaResponse = await this.media.saveMedias(0, files);
    res.json({status: true});
}

คำตอบ #1

ก่อนอื่น: การใช้ multer ผ่าน FilesInterceptor ที่มีอยู่แล้ว และ FilesMiddleware แบบกำหนดเองพร้อมกันนั้นไม่มีความหมาย เลือก หนึ่ง ในตัวเลือกสองข้อดังต่อไปนี้:

A) ใช้ FilesInterceptor ที่มีมาในตัว (แนะนำ)

คุณสามารถกำหนดค่าที่เก็บข้อมูลของคุณโดยตรงสำหรับ FilesInterceptor แต่ละตัวได้:

const storage = {...};

@Controller()
export class AppController {

  @Post('upload')
  @UseInterceptors(FilesInterceptor('files', 20, { storage }))
  public async onUpload(@UploadedFiles() files) {
    return files.map(file => file.filename);
  }
}

หรือจัดหาการกำหนดค่า storage แบบเริ่มต้นของ multer โดยการนำเข้า MulterModule:

imports: [
  MulterModule.register({
    storage: {...},
  })
]

B) การใช้ middleware ของคุณเอง (โดยไม่ใช้ FilesInterceptor)

ใช้สิ่งนี้เฉพาะเมื่อคุณต้องการความยืดหยุ่นมากกว่าที่ FilesInterceptor ให้ คุณสามารถใช้ Promise เพื่อรอให้การอัปโหลดเสร็จสิ้น หลังจากการอัปโหลด คุณสามารถเข้าถึงชื่อไฟล์ใหม่ได้ผ่าน req.files

export class FilesMiddleware implements NestMiddleware {
  private storage = {...};

  async use(req, res, next) {
    const upload = multer({ storage: this.storage });
    // wait until upload has finished
    await new Promise((resolve, reject) => {
      upload.array('files')(req, res, err => err ? reject(err) : resolve());
    });
    // Then you can access the new file names
    console.log(req.files.map(file => file.filename));
    return next();
  }
}

เข้าถึงไฟล์ที่อัปโหลดในคอนโทรลเลอร์ของคุณผ่านออบเจ็กต์ request:

@Post('upload')
public async onUpload(@Request() req) {
  return req.files.map(file => file.filename);
}

จะเข้าถึงชื่อไฟล์ใหม่ได้อย่างไร?

คุณจะพบไฟล์ที่อัปโหลดใน req.files (middleware) หรือ @UploadedFiles() files (interceptor) ในรูปแบบอาร์เรย์ที่มีโครงสร้างดังนี้:

[ { fieldname: 'files',
    originalname: 'originalname.json',
    encoding: '7bit',
    mimetype: 'application/json',
    destination: 'D:/myproject/src/uploads',
    // This is what you are looking for
    filename: 'files-1558459911159.json',
    path:
     'D:/myproject/src/uploads/files-1558459911159.json',
    size: 2735 } ]

บทความที่เกี่ยวข้อง