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
npm install multeryarn add multerpnpm add multerbun add multermulter does not include its own TypeScript type definitions. If you use TypeScript, also install the community-maintained types from DefinitelyTyped as a development dependency:
npm install --save-dev @types/multeryarn add --dev @types/multerpnpm add --save-dev @types/multerbun add --dev @types/multerUsage
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és | Libellé | Note |
|---|---|---|
nomdechamp | Nom du champ spécifié dans le formulaire | |
nomoriginal | Name of the file on the user’s computer, or the full path when preservePath: true | |
encodage | Type d’encodage du fichier | |
mimetype | Type Mime du fichier | |
size | Taille du fichier en octets | |
destination | Le dossier dans lequel le fichier a été sauvegardé | DiskStorage |
filename | Le nom du fichier dans la destination | DiskStorage |
path | Le chemin complet vers le fichier téléchargé | DiskStorage |
tampon | Un Buffer du fichier entier | Stockage 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és | Libellé |
|---|---|
defCharset | Default character set to use for text field values that do not declare one. Default: 'utf8' |
defParamCharset | Le 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 storage | Où stocker les fichiers |
fileFilter | Fonction pour contrôler quels fichiers sont acceptés |
fileHwm | highWaterMark of each file stream (file.stream). Default: busboy’s default |
highWaterMark | highWaterMark of the multipart parser stream. Default: busboy’s default |
limites | Limites des données téléchargées |
preservePath | Keep the full client-supplied path in file.originalname instead of just the base name |
streamHandler | Function 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és | Libellé | Par défaut |
|---|---|---|
fieldNameSize | Taille maximale du nom du champ | Infini |
fieldSize | Taille maximale du champ (en octets) | 1 Mo |
champs | Nombre maximum de champs hors fichier | Infini |
fileSize | Pour les formes multiparties, la taille maximale du fichier (en octets) | Infini |
fichiers | Pour les formulaires en plusieurs parties, le nombre maximum de champs de fichier | Infini |
Parties | Pour les formes multiparties, le nombre maximum de parties (champs + fichiers) | Infini |
headerPairs | Pour les formes multiparties, le nombre maximum de clés d’en-tête =>valeur à analyser | 2000 |
fieldNestingDepth | Max number of nesting levels for field names (e.g. a[b][c] has 2 levels) | Infini |
fieldArrayIndexLimit | Max 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 casefiles— set to the maximum number of files per requestfields— set to the maximum number of text fields per requestfieldNestingDepth— set to the minimum depth your field names require (e.g.3fora[b][c])fieldArrayIndexLimit— set to the largest array index your field names require (e.g.100fora[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.