Multipart-lataukset Multer-sieppaajilla
Määritä FileInterceptor ja FilesInterceptor vastaanottamaan yhden ja usean tiedoston latauksia kokorajoituksilla.
Multipart-lataukset Multer-sieppaajilla on ilmainen NestJS-yritysbackendien API:t-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu NestJS-yritysbackendien API:t-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. NestJS-yritysbackendien API:t-kurssilla on yhteensä 4 oppituntia.
Miksi Multeria käytetään latauksiin
HTTP-tiedostolataukset käyttävät multipart/form-data-sisältötyyppiä, joka jakaa pyynnön rungon osiin: tekstikenttiin ja binaarisiin tiedostosisältöihin, jotka erotetaan rajamerkillä.
NestJS ei jäsennä tätä muotoa itse. Sen sijaan se tarjoaa valmiit kääreet Multer-kirjastolle, joka on Expressin de facto -väliohjelmisto multipart-jäsentämiseen. Multeria käytetään interceptoreiden kautta sen sijaan, että väliohjelmisto kytkettäisiin manuaalisesti.
FileInterceptor— yksi tiedosto yhdestä kentästäFilesInterceptor— useita tiedostoja yhdestä kentästäFileFieldsInterceptor— tiedostoja useista nimetyistä kentistä
Tässä oppitunnissa keskitytään kahteen ensimmäiseen sekä kokorajojen määrittämiseen.
Tyyppien asentaminen
Interceptorit sijaitsevat paketissa @nestjs/platform-express, joka sisältyy jo tavalliseen Nest-sovellukseen. Tarvitsette vain Multerin tyyppimääritykset, jotta käsittelijän parametrit voidaan tyypittää oikein.
Asentakaa kehitysriippuvuus, jotta TypeScript tunnistaa tyypin Express.Multer.File:
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.Yksittäinen tiedosto FileInterceptorilla
Liittäkää FileInterceptor('field') käyttöön @UseInterceptors-merkinnällä. Merkkijono on tiedoston sisältävän form-data-kentän nimi. Lukekaa sitten jäsennelty tiedosto @UploadedFile()-koristelijan avulla.
Koristeltu parametri on yksittäinen Express.Multer.File. Huomatkaa, että lomakkeen parametrin nimen ei tarvitse vastata käsittelijän argumentin nimeä — vain interceptorin kenttämerkkijonolla on merkitystä.
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,
};
}
}Muistissa vai levyllä säilyttäminen
Oletusarvoisesti Multer käyttää muistivarastoa: koko tiedosto sijoitetaan file.buffer-ominaisuuteen Bufferina. Tämä on kätevää, kun tiedosto välitetään S3:een tai käsitellään prosessin sisällä, mutta suuret tiedostot voivat kuluttaa kaiken RAM-muistin.
Paikallista tallennusta varten käyttäkää levyvarastoa, jossa Multer kirjoittaa tietovirran polkuun ja antaa puskurin sijaan file.path-ominaisuuden. Välittäkää asetukset interceptorin toisena argumenttina.
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 }))Kokorajan pakottaminen
Älkää koskaan luottako asiakkaan ilmoittamiin kokoihin. Rajoittakaa Multerin hyväksymien tavujen määrä limits.fileSize-asetuksella (tavuina). Kun tiedosto ylittää rajan, Multer keskeyttää käsittelyn ja Nest palauttaa 413-tyyppisen virheen ennen käsittelijän suorittamista.
Yhdistäkää fileSize asetukseen files, jotta voitte rajoittaa myös monilatauksen tiedostomäärää.
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 };
}Rajojen laskeminen turvallisesti
Expressin rajat ilmoitetaan raakoina tavuina, joten suuruusluokan voi helposti laskea väärin. Pieni puhdas apufunktio pitää laskutoimituksen selkeänä ja testattavana, ja se toimii kaikkialla ilman kehystä.
Alla mb muuntaa megatavut tavuiksi, ja ehdokaslatauksen koko tarkistetaan ylärajaa vasten.
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)Useita tiedostoja FilesInterceptorilla
FilesInterceptor('field', maxCount, options) hyväksyy useita tiedostoja, jotka lähetetään saman kentänimen alla. Lukekaa ne @UploadedFiles()-koristelijalla, joka palauttaa taulukon.
maxCount-argumentti on ehdoton yläraja Nestin keräämälle tiedostomäärälle; ylimääräiset tiedostot aiheuttavat virheen. Yhdistäkää siihen limits.fileSize tiedostokohtaisten tavurajojen määrittämiseksi.
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 }));
}
}Suodattaminen MIME-tyypin perusteella
Kokorajat eivät estä väärän tiedostotyypin lähettämistä. Käyttäkää fileFilter-asetusta kunkin osan hyväksymiseen tai hylkäämiseen sen saapuessa. Kutsukaa callbackia argumentilla (null, true) tiedoston säilyttämiseksi tai antakaa sille virhe tiedoston hylkäämiseksi.
BadRequestException-virheellä hylkääminen tuottaa selkeän 400-vastauksen yleisen virheen sijaan.
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);
}Validointi ParseFilePipella
Nestin sisäänrakennettu ParseFilePipe validoi jo jäsennellyn tiedoston deklaratiivisesti käsittelijän sisällä. Se yhdistää esimerkiksi MaxFileSizeValidator- ja FileTypeValidator-validoijat ja palauttaa virhetilanteessa 422-vastauksen.
Tämä täydentää Multerin limits-asetusta: Multer suojaa tietovirtaa, kun taas putki valvoo liiketoimintasääntöjä ja antaa selkeämmät virheilmoitukset.
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 };
}Määritysten keskittäminen tehtaaseen
Tallennuksen, rajojen ja suodattimien toistaminen jokaisella reitillä altistaa virheille. Poimikaa yksi MulterOptions-objekti (tai tehdas) ja käyttäkää sitä uudelleen. Yrityssovelluksissa oletukset rekisteröidään usein maailmanlaajuisesti komennolla MulterModule.register(), ja reittikohtaisia asetuksia muutetaan vain tarvittaessa.
Näin rajat pysyvät yhdenmukaisina, ja rajan korottaminen vaatii vain yhden rivin muutoksen.
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))Kokorajan ylitysvirheen käsittely
Kun limits.fileSize ylittyy, Multer aiheuttaa virheen, jonka code on 'LIMIT_FILE_SIZE'. Oletusarvoisesti Nest käärii virheen, mutta voitte muuntaa sen selkeäksi hyötykuormaksi poikkeussuodattimen avulla, jolloin asiakkaat saavat ymmärrettävän ja yhdenmukaisen ilmoituksen.
Matalan tason Multer-koodien muuntaminen HTTP-vastauksiksi on tuotantotasoisten latausrajapintojen tunnusmerkki.
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 });
}
}Pikatarkistus
Testatkaa, ymmärrättekö oikean interceptorin valinnan ja sen tuloksen lukemisen.
Kertaus
Osaatte nyt toteuttaa multipart-lataukset NestJS:ssä alusta loppuun:
- FileInterceptor('field', options) +
@UploadedFile()yhdelle tiedostolle. - FilesInterceptor('field', maxCount, options) +
@UploadedFiles()useille saman kentän alla oleville tiedostoille. - limits.fileSize rajoittaa tietovirran kokoa tavuina, limits.files tiedostomäärää ja fileFilter hylkää virheelliset MIME-tyypit varhaisessa vaiheessa.
- diskStorage ja muistivarasto määrittävät, saadaanko käyttöön
file.pathvaifile.buffer. - ParseFilePipe yhdessä
MaxFileSizeValidator/FileTypeValidator-validoijien kanssa suorittaa deklaratiivisen validoinnin, ja MulterError-suodatin muuntaaLIMIT_FILE_SIZE-virheen selkeäksi 413-vastaukseksi.
Keskittäkää nämä asetukset yhteen tehtaaseen, jotta rajat pysyvät yhdenmukaisina kaikilla latausreiteillä.
Opi TypeScript tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 20
- Oppitunnit
- 76
Usein kysytyt kysymykset
Onko oppitunti ”Multipart-lataukset Multer-sieppaajilla” ilmainen?
Kyllä – oppitunnin ”Multipart-lataukset Multer-sieppaajilla” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko NestJS-yritysbackendien API:t-kurssin, päivitä CoddyKit PROhon. NestJS-yritysbackendien API:t-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Multipart-lataukset Multer-sieppaajilla”?
Määritä FileInterceptor ja FilesInterceptor vastaanottamaan yhden ja usean tiedoston latauksia kokorajoituksilla. Harjoittelet NestJS-yritysbackendien API:t-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni NestJS-yritysbackendien API:t-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin NestJS-yritysbackendien API:t-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”Multipart-lataukset Multer-sieppaajilla”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä NestJS-yritysbackendien API:t-oppitunnilla?
Kyllä. Jokainen NestJS-yritysbackendien API:t-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Multipart-lataukset Multer-sieppaajilla
- Suurten vastausten suoratoisto StreamableFilella
- Suorat S3-lataukset allekirjoitetuilla URL-osoitteilla
- Kuvankäsittelyputket Sharpilla