NestJS-API-er for virksomhetsbackend · leksjon

Multipart-opplastinger med Multer-interceptorer

Koble til FileInterceptor og FilesInterceptor for å ta imot opplastinger av én eller flere filer med størrelsesbegrensninger.

Leksjon 1 av 413 trinn

Multipart-opplastinger med Multer-interceptorer er en gratis leksjon i NestJS-API-er for virksomhetsbackend på CoddyKit. Dette er leksjon 1 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i NestJS-API-er for virksomhetsbackend, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i NestJS-API-er for virksomhetsbackend inneholder totalt 4 leksjoner.

Hvorfor Multer brukes til opplastinger

HTTP-filopplastinger bruker innholdstypen multipart/form-data, som deler forespørselsteksten inn i deler: tekstfelt og binære nyttelaster for filer, atskilt av en grensemarkør.

NestJS analyserer ikke dette formatet på egen hånd. I stedet leverer rammeverket førsteklasses omslag rundt Multer, den de facto Express-mellomvaren for analyse av multipart-forespørsler. Du bruker Multer gjennom interceptorer i stedet for å koble til mellomvare manuelt.

  • FileInterceptor — én fil fra ett felt
  • FilesInterceptor — flere filer fra ett felt
  • FileFieldsInterceptor — filer fra flere navngitte felt

Denne leksjonen fokuserer på de to første og på håndheving av størrelsesgrenser.

Installere typene

Interceptorene ligger i @nestjs/platform-express, som allerede finnes i en standard Nest-app. Du trenger bare Multer-typedefinisjonene for å angi riktige typer for handler-parametere.

Installer utviklingsavhengigheten slik at Express.Multer.File gjenkjennes av TypeScript:

npm install -D @types/multer

// Now Express.Multer.File is available globally in TypeScript.
// It describes the in-memory/disk file object Multer attaches
// to the request, e.g. originalname, mimetype, size, buffer, path.

Én fil med FileInterceptor

Koble FileInterceptor('field') til @UseInterceptors, der strengen er navnet på form-data-feltet som inneholder filen. Les deretter den analyserte filen med dekoratøren @UploadedFile().

Den dekorerte parameteren er én Express.Multer.File. Legg merke til at parameternavnet i skjemaet ikke trenger å samsvare med handler-argumentet — det er bare interceptorens feltstreng som betyr noe.

import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

@Controller('avatars')
export class AvatarsController {
  @Post()
  @UseInterceptors(FileInterceptor('avatar'))
  upload(@UploadedFile() file: Express.Multer.File) {
    return {
      name: file.originalname,
      type: file.mimetype,
      size: file.size,
    };
  }
}

Lagring i minnet kontra på disk

Som standard bruker Multer lagring i minnet: Hele filen havner i file.buffer som en Buffer. Dette er praktisk når filen skal videresendes til S3 eller behandles i prosessen, men store filer kan fylle opp RAM.

Bruk disklagring for lokal lagring. Da strømmer Multer filen til en bane og gir deg file.path i stedet for en buffer. Send alternativer som det andre argumentet til interceptoren.

import { diskStorage } from 'multer';
import { extname } from 'path';
import { randomUUID } from 'crypto';

export const imageStorage = diskStorage({
  destination: './uploads/images',
  filename: (_req, file, cb) => {
    const unique = randomUUID();
    cb(null, `${unique}${extname(file.originalname)}`);
  },
});

// Usage:
// @UseInterceptors(FileInterceptor('photo', { storage: imageStorage }))

Håndheve en størrelsesgrense

Stol aldri på størrelser som klienten oppgir. Begrens antallet byte Multer godtar, via alternativet limits.fileSize (i byte). Når en fil overskrider grensen, avbryter Multer, og Nest videreformidler en feil av typen 413 før handleren kjøres.

Kombiner fileSize med files for også å begrense antallet filer i en fleropplasting.

import { FileInterceptor } from '@nestjs/platform-express';

const FIVE_MB = 5 * 1024 * 1024;

@Post('avatar')
@UseInterceptors(
  FileInterceptor('avatar', {
    limits: { fileSize: FIVE_MB },
  }),
)
upload(@UploadedFile() file: Express.Multer.File) {
  return { stored: file.originalname };
}

Beregne grenser på en trygg måte

Express-grenser uttrykkes i rå byte, og det er lett å bomme med en størrelsesorden. En liten, ren hjelpefunksjon gjør beregningen tydelig og testbar, og den kan kjøres hvor som helst uten et rammeverk.

Nedenfor konverterer mb megabyte til byte, og vi kontrollerer at en foreslått opplastingsstørrelse holder seg innenfor en grense.

function mb(n: number): number {
  return n * 1024 * 1024;
}

function withinLimit(sizeBytes: number, capMb: number): boolean {
  return sizeBytes <= mb(capMb);
}

const FILE_CAP_MB = 5;
console.log('5MB in bytes:', mb(FILE_CAP_MB));
console.log(withinLimit(mb(4), FILE_CAP_MB));   // true
console.log(withinLimit(mb(6), FILE_CAP_MB));   // false
console.log(withinLimit(5_242_880, FILE_CAP_MB)); // true (exactly 5MB)

Flere filer med FilesInterceptor

FilesInterceptor('field', maxCount, options) godtar flere filer som sendes under det samme feltnavnet. Les dem med @UploadedFiles(), som returnerer en tabell.

Argumentet maxCount er en absolutt grense for hvor mange filer Nest samler inn; ekstra filer utløser en feil. Kombiner det med limits.fileSize for en grense i byte per fil.

import { Controller, Post, UploadedFiles, UseInterceptors } from '@nestjs/common';
import { FilesInterceptor } from '@nestjs/platform-express';

@Controller('gallery')
export class GalleryController {
  @Post()
  @UseInterceptors(
    FilesInterceptor('photos', 10, {
      limits: { fileSize: 5 * 1024 * 1024 },
    }),
  )
  upload(@UploadedFiles() files: Express.Multer.File[]) {
    return files.map((f) => ({ name: f.originalname, size: f.size }));
  }
}

Filtrere etter MIME-type

Størrelsesgrenser hindrer ikke feil filtype. Bruk fileFilter til å godta eller avvise hver del mens den strømmes. Kall tilbakekallingsfunksjonen med (null, true) for å beholde en fil, eller med en feil for å avvise den.

Hvis du avviser med en BadRequestException, får du en ryddig 400 i stedet for en generell feil.

import { BadRequestException } from '@nestjs/common';
import { Request } from 'express';

export function imageFileFilter(
  _req: Request,
  file: Express.Multer.File,
  cb: (error: Error | null, accept: boolean) => void,
) {
  const allowed = ['image/png', 'image/jpeg', 'image/webp'];
  if (!allowed.includes(file.mimetype)) {
    return cb(new BadRequestException('Only PNG, JPEG, or WebP allowed'), false);
  }
  cb(null, true);
}

Validere med ParseFilePipe

Nests innebygde ParseFilePipe validerer den allerede analyserte filen deklarativt inne i handleren. Den kombinerer validatorer som MaxFileSizeValidator og FileTypeValidator, og returnerer 422 når de feiler.

Dette kommer i tillegg til Multers limits: Multer beskytter strømmen, mens pipen håndhever forretningsreglene dine og gir tydeligere feilmeldinger.

import {
  ParseFilePipe,
  MaxFileSizeValidator,
  FileTypeValidator,
  UploadedFile,
} from '@nestjs/common';

@Post('avatar')
@UseInterceptors(FileInterceptor('avatar'))
upload(
  @UploadedFile(
    new ParseFilePipe({
      validators: [
        new MaxFileSizeValidator({ maxSize: 5 * 1024 * 1024 }),
        new FileTypeValidator({ fileType: /(png|jpe?g|webp)$/ }),
      ],
    }),
  )
  file: Express.Multer.File,
) {
  return { ok: true, name: file.originalname };
}

Sentralisere konfigurasjon med en fabrikk

Det er feilutsatt å gjenta lagring, grenser og filtre for hver rute. Trekk ut ett MulterOptions-objekt (eller en fabrikk) og bruk det på nytt. Enterprise-apper registrerer ofte standardverdier globalt via MulterModule.register() og overstyrer dem per rute bare ved behov.

Da blir grensene konsekvente, og det å øke en grense krever bare én linje.

import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface';
import { diskStorage } from 'multer';
import { imageFileFilter } from './image-file.filter';

export const imageUploadOptions: MulterOptions = {
  storage: diskStorage({ destination: './uploads/images' }),
  limits: { fileSize: 5 * 1024 * 1024, files: 10 },
  fileFilter: imageFileFilter,
};

// @UseInterceptors(FilesInterceptor('photos', 10, imageUploadOptions))

Håndtere feilen for størrelsesgrensen

Når limits.fileSize overskrides, kaster Multer en feil med code-verdien 'LIMIT_FILE_SIZE'. Som standard pakker Nest den inn, men du kan omforme den til en brukervennlig nyttelast med et unntaksfilter, slik at klientene får en tydelig og konsekvent melding.

Å oversette Multers lavnivåkoder til HTTP-svar er et kjennetegn på opplastingsendepunkter av produksjonskvalitet.

import { ExceptionFilter, Catch, ArgumentsHost, HttpStatus } from '@nestjs/common';
import { MulterError } from 'multer';
import { Response } from 'express';

@Catch(MulterError)
export class MulterExceptionFilter implements ExceptionFilter {
  catch(err: MulterError, host: ArgumentsHost) {
    const res = host.switchToHttp().getResponse<Response>();
    const status =
      err.code === 'LIMIT_FILE_SIZE'
        ? HttpStatus.PAYLOAD_TOO_LARGE
        : HttpStatus.BAD_REQUEST;
    res.status(status).json({ statusCode: status, message: err.message });
  }
}

Kort kontroll

Test om du forstår hvordan du velger riktig interceptor og leser resultatet fra den.

Oppsummering

Du kan nå koble multipart-opplastinger sammen fra ende til annen i NestJS:

  • FileInterceptor('field', options) + @UploadedFile() for én fil.
  • FilesInterceptor('field', maxCount, options) + @UploadedFiles() for flere filer under ett felt.
  • limits.fileSize (byte) begrenser størrelsen på strømmen; limits.files begrenser antallet; fileFilter avviser ugyldige MIME-typer tidlig.
  • diskStorage kontra minnelagring avgjør om du får file.path eller file.buffer.
  • ParseFilePipe med MaxFileSizeValidator/FileTypeValidator validerer deklarativt, og et MulterError-filter oversetter LIMIT_FILE_SIZE til en ryddig 413.

Samle disse alternativene i én fabrikk, slik at grensene forblir konsekvente på tvers av alle opplastingsruter.

Gratis å komme i gang

Lær deg TypeScript med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
20
Leksjoner
76

Ofte stilte spørsmål

Er leksjonen «Multipart-opplastinger med Multer-interceptorer» gratis?

Ja – hele teksten i «Multipart-opplastinger med Multer-interceptorer» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av NestJS-API-er for virksomhetsbackend-kurset, kan du oppgradere til CoddyKit PRO. Kurset i NestJS-API-er for virksomhetsbackend inneholder totalt 4 leksjoner.

Hva lærer jeg i «Multipart-opplastinger med Multer-interceptorer»?

Koble til FileInterceptor og FilesInterceptor for å ta imot opplastinger av én eller flere filer med størrelsesbegrensninger. Du øver på NestJS-API-er for virksomhetsbackend med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med NestJS-API-er for virksomhetsbackend?

Ingen tidligere erfaring er nødvendig. NestJS-API-er for virksomhetsbackend på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.

Hvor lang tid tar leksjonen «Multipart-opplastinger med Multer-interceptorer»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne NestJS-API-er for virksomhetsbackend-leksjonen?

Ja. Alle NestJS-API-er for virksomhetsbackend-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Multipart-opplastinger med Multer-interceptorer
  2. Strømme store svar med StreamableFile
  3. Direkteopplastinger til S3 med forhåndssignerte URL-er
  4. Pipelines for bildebehandling med Sharp
← Tilbake til NestJS-API-er for virksomhetsbackend