multer middleware

Multer est un middleware de node.js pour gérer multipart/form-data, qui est principalement utilisé pour le téléchargement de fichiers. Il est écrit au-dessus de busboy pour une efficacité maximale.

REMARQUE : Multer ne traitera aucun formulaire qui n’est pas multipartie (multipart/form-data).

Installation

Terminal window
npm install multer

multer does not include its own TypeScript type definitions. If you use TypeScript, also install the community-maintained types from DefinitelyTyped as a development dependency:

Terminal window
npm install --save-dev @types/multer

Usage

Multer ajoute un objet body et un objet file ou files à l’objet request. L’objet body contient les valeurs des champs de texte du formulaire, l’objet file ou files contient les fichiers téléchargés via le formulaire.

Exemple d’utilisation de base :

N’oubliez pas le fichier enctype="multipart/form-data" dans votre formulaire.

<form action="/profile" method="post" enctype="multipart/form-data">
<input type="file" name="avatar" />
</form>
const express = require('express');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
const app = express();
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
});
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
});
const uploadMiddleware = upload.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 },
]);
app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
// req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
//
// e.g.
// req.files['avatar'][0] -> File
// req.files['gallery'] -> Array
//
// req.body will contain the text fields, if there were any
});

Dans le cas où vous avez besoin de gérer une forme multipart uniquement en texte, vous devez utiliser la méthode .none() :

const express = require('express');
const app = express();
const multer = require('multer');
const upload = multer();
app.post('/profile', upload.none(), function (req, res, next) {
// req.body contains the text fields
});

Voici un exemple sur la façon dont le multer est utilisé dans une forme HTML. Prenez note des champs enctype="multipart/form-data" et name="uploaded_file" :

<form action="/stats" enctype="multipart/form-data" method="post">
<div class="form-group">
<input type="file" class="form-control-file" name="uploaded_file" />
<input type="text" class="form-control" placeholder="Number of speakers" name="nspeakers" />
<input type="submit" value="Get me the stats!" class="btn btn-default" />
</div>
</form>

Ensuite, dans votre fichier javascript, vous ajouterez ces lignes pour accéder au fichier et au corps. Il est important que vous utilisiez la valeur du champ name à partir du formulaire dans votre fonction de téléchargement. Cela indique au multer dans quel champ il doit chercher les fichiers. Si ces champs ne sont pas identiques dans le formulaire HTML et sur votre serveur, votre envoi échouera :

const multer = require('multer');
const upload = multer({ dest: './public/data/uploads/' });
app.post('/stats', upload.single('uploaded_file'), function (req, res) {
// req.file is the name of your file in the form above, here 'uploaded_file'
// req.body will hold the text fields, if there were any
console.log(req.file, req.body);
});

Complete client-side and server-side examples (browser FormData uploads of a blob and of an image) are in the examples/ folder.

API

Informations sur le fichier

Chaque fichier contient les informations suivantes :

ClésLibelléNote
nomdechampNom du champ spécifié dans le formulaire
nomoriginalName of the file on the user’s computer, or the full path when preservePath: true
encodageType d’encodage du fichier
mimetypeType Mime du fichier
sizeTaille du fichier en octets
destinationLe dossier dans lequel le fichier a été sauvegardéDiskStorage
filenameLe nom du fichier dans la destinationDiskStorage
pathLe chemin complet vers le fichier téléchargéDiskStorage
tamponUn Buffer du fichier entierStockage mémoire

multer(opts)

Multer accepte un objet d’options, dont le plus basique est la propriété dest qui indique à Multer où envoyer les fichiers. Si vous omettez l’objet d’options , les fichiers seront conservés en mémoire et ne seront jamais écrits sur le disque.

Par défaut, Multer renommera les fichiers pour éviter de nommer les conflits. La fonction de renommage peut être personnalisée en fonction de vos besoins.

Voici les options qui peuvent être passées à Multer.

ClésLibellé
defCharsetDefault character set to use for text field values that do not declare one. Default: 'utf8'
defParamCharsetLe jeu de caractères par défaut à utiliser pour les valeurs des paramètres de l’en-tête de la partie (par exemple le nom du fichier) qui ne sont pas des paramètres étendus (contenant un jeu de caractères explicite). Par défaut: 'latin1'
dest ou storageOù stocker les fichiers
fileFilterFonction pour contrôler quels fichiers sont acceptés
fileHwmhighWaterMark of each file stream (file.stream). Default: busboy’s default
highWaterMarkhighWaterMark of the multipart parser stream. Default: busboy’s default
limitesLimites des données téléchargées
preservePathKeep the full client-supplied path in file.originalname instead of just the base name
streamHandlerFunction that feeds the request body to busboy; defaults to req.pipe(busboy)

Dans une application web moyenne, seul dest peut être requis, et configuré comme montré dans l’exemple suivant.

const upload = multer({ dest: 'uploads/' });

When preservePath is enabled, Multer passes the incoming filename through with any path segments provided by the client. This is exposed as file.originalname; it does not change the destination folder, create directories, or sanitize the path for you. file.originalname is always client-supplied and should be treated as untrusted; with preservePath it additionally contains the path segments the client sent. Normalize or validate it before using it in a custom filename or storage engine.

Si vous voulez plus de contrôle sur vos envois, vous voudrez utiliser l’option storage au lieu de dest. Multer est livré avec des moteurs de stockage DiskStorage et MemoryStorage; Plus de moteurs sont disponibles auprès de tiers.

.single(nom du champ)

Accepter un seul fichier avec le nom fieldname. Le fichier unique sera stocké dans req.file.

.array(fieldname[, maxCount])

Accepte un tableau de fichiers, tous avec le nom fieldname. Erreur optionnelle si plus que les fichiers maxCount sont téléchargés. Le tableau de fichiers sera stocké dans req.files.

Files skipped by fileFilter do not count towards maxCount. Use limits.files to bound how many files are read from a request.

.fields(fields)

Accepte un mélange de fichiers, spécifié par fields. Un objet avec des tableaux de fichiers sera stocké dans req.files.

fields doit être un tableau d’objets avec name et éventuellement un maxCount. Exemple:

[
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 },
];

.none()

Accepter uniquement les champs de texte. If any file upload is made, error with code LIMIT_UNEXPECTED_FILE will be issued.

.any()

Accepts all files that come over the wire. Un tableau de fichiers sera stocké dans req.files.

AVERTISSEMENT : Assurez-vous de toujours gérer les fichiers qu’un utilisateur téléverse. N’ajoutez jamais de multer en tant que middleware global car un utilisateur malveillant pourrait télécharger des fichiers sur une route que vous n’aviez pas anticipée. Utilisez cette fonction uniquement sur les routes où vous gérez les fichiers téléchargés.

stockage

DiskStorage

Le moteur de stockage de disque vous donne un contrôle total sur le stockage des fichiers sur disque.

const crypto = require('crypto');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads');
},
filename: function (req, file, cb) {
crypto.randomBytes(16, function (err, raw) {
if (err) return cb(err);
cb(null, file.fieldname + '-' + raw.toString('hex'));
});
},
});
const upload = multer({ storage: storage });

There are three options available: destination, filename and flush. All of them except flush are functions that determine where the file should be stored.

destination is used to determine within which folder the uploaded files should be stored. Cela peut également être donné en tant que string (par exemple '/tmp/uploads'). Si aucun destination n’est donné, le répertoire par défaut du système d’exploitation pour les fichiers temporaires est utilisé.

Note: Vous êtes responsable de la création du répertoire lorsque vous fournissez destination en tant que fonction. Lorsque vous passez une chaîne, multer s’assurera que le répertoire est créé pour vous.

filename est utilisé pour déterminer ce que le fichier doit être nommé dans le dossier. If no filename is given, each file will be given a random name that doesn’t include any file extension.

Note: Multer n’ajoutera aucune extension de fichier pour vous, votre fonction devrait retourner un nom de fichier complet avec une extension de fichier.

Chaque fonction est passée à la fois la requête (req) et quelques informations sur le fichier (file) pour aider à la décision.

Notez que req.body pourrait ne pas encore avoir été entièrement peuplé. Cela dépend de l’ordre que le client transmet des champs et des fichiers au serveur.

Pour comprendre la convention d’appel utilisée dans le callback (avoir besoin de passer null comme premier paramètre), reportez-vous à Node. s gestion des erreurs

flush is an optional boolean. When set to true, the file data is flushed to disk with an fsync call before the upload handler runs, which prevents data loss if the process or the system crashes while the data is still sitting in the operating system’s page cache. It is disabled by default because forcing a disk flush on every upload has a performance cost. Note that this syncs the file contents only; if the new directory entry must survive a crash as well, fsync the destination directory yourself.

Stockage mémoire

Le moteur de stockage de mémoire stocke les fichiers en mémoire comme des objets Buffer. It doesn’t have any options.

const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

Lors de l’utilisation du stockage mémoire, les informations sur le fichier contiendront un champ appelé buffer qui contient le fichier entier.

WARNING: Uploading very large files, or relatively small files in large numbers very quickly, can cause your application to run out of memory when memory storage is used.

limites

Un objet spécifiant les limites de taille des propriétés optionnelles suivantes. Multer passes this object into busboy directly, and the details of the properties can be found on busboy’s page.

limits can also be a function that receives the request and returns such an object. It is called once per request, before parsing starts, so limits can depend on e.g. the authenticated user:

const upload = multer({
limits: function (req) {
return { fileSize: req.user.maxUploadSize };
},
});

Limits apply to the whole request; there is no per-file limit. To restrict individual files by type or name, use fileFilter or a custom storage engine.

Les valeurs entières suivantes sont disponibles :

ClésLibelléPar défaut
fieldNameSizeTaille maximale du nom du champInfini
fieldSizeTaille maximale du champ (en octets)1 Mo
champsNombre maximum de champs hors fichierInfini
fileSizePour les formes multiparties, la taille maximale du fichier (en octets)Infini
fichiersPour les formulaires en plusieurs parties, le nombre maximum de champs de fichierInfini
PartiesPour les formes multiparties, le nombre maximum de parties (champs + fichiers)Infini
headerPairsPour les formes multiparties, le nombre maximum de clés d’en-tête =>valeur à analyser2000
fieldNestingDepthMax number of nesting levels for field names (e.g. a[b][c] has 2 levels)Infini
fieldArrayIndexLimitMax numeric array index accepted inside a field name (e.g. a[3] uses index 3)Infini

Spécifier les limites peut aider à protéger votre site contre les attaques par déni de service (DoS).

fileFilter

Définissez ceci à une fonction pour contrôler quels fichiers doivent être téléchargés et quels doivent être ignorés. La fonction devrait ressembler à ceci :

function fileFilter(req, file, cb) {
// The function should call `cb` with a boolean
// to indicate if the file should be accepted
// To reject this file pass `false`, like so:
cb(null, false);
// To accept the file pass `true`, like so:
cb(null, true);
// You can always pass an error if something goes wrong:
cb(new Error("I don't have a clue!"));
}

streamHandler

By default Multer reads the request with req.pipe(busboy). Some platforms consume the request body before your handlers run, so there is nothing left to pipe. Google Cloud Functions and Firebase Functions, for example, expose the already-read body as req.rawBody. Provide a streamHandler to feed busboy yourself in that case:

const upload = multer({
storage: multer.memoryStorage(),
streamHandler: function (req, busboy) {
if (req.rawBody) {
busboy.end(req.rawBody);
} else {
req.pipe(busboy);
}
},
});

The function receives the request and the busboy instance and must write the whole multipart body to busboy and end it.

Security

Specifying the limits can help protect your site against denial of service (DoS) attacks. The following limits are recommended for most applications:

  • fileSize — set to the maximum expected file size for your use case
  • files — set to the maximum number of files per request
  • fields — set to the maximum number of text fields per request
  • fieldNestingDepth — set to the minimum depth your field names require (e.g. 3 for a[b][c])
  • fieldArrayIndexLimit — set to the largest array index your field names require (e.g. 100 for a[99])

Gestion des erreurs

En cas d’erreur, Multer délègue l’erreur à Express. Vous pouvez afficher une belle page d’erreur en utilisant le type express way.

Si vous voulez attraper des erreurs spécifiques à Multer, vous pouvez appeler la fonction middleware par vous-même. Aussi, si vous voulez attraper seulement les erreurs Multer, vous pouvez utiliser la classe MulterError qui est attachée à l’objet multer lui-même (e. . err instanceof multer.MulterError).

Multer errors carry a code (e.g. LIMIT_FILE_SIZE) and, when the error concerns a specific field, its name in field. Errors about a specific file (LIMIT_FILE_SIZE, LIMIT_UNEXPECTED_FILE) also expose the client-supplied file name in filename; treat it as untrusted input, like file.originalname.

const multer = require('multer');
const upload = multer().single('avatar');
app.post('/profile', function (req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
} else if (err) {
// An unknown error occurred when uploading.
}
// Everything went fine.
});
});

Moteur de stockage personnalisé

Pour plus d’informations sur la façon de construire votre propre moteur de stockage, voir Multer Storage Engine.

Licence

MIT