multer Middleware

Multer ist eine Middleware von node.js für den Umgang mit multipart/form-data, die hauptsächlich zum Hochladen von Dateien verwendet wird. Es wird oben auf busboy geschrieben, um maximale Effizienz zu erzielen.

HINWEIS: Multer wird keine Form verarbeiten, die nicht multipart ist (multipart/form-data).

Installation

Terminal window
npm install multer

Note

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

Auslastung

Multer fügt dem request Objekt ein body und ein file oder files Objekt hinzu. Das body Objekt enthält die Werte der Textfelder der Form, das file oder files Objekt enthält die Dateien, die über das Formular hochgeladen werden.

Einfaches Nutzungsbeispiel:

Vergessen Sie nicht die enctype="multipart/form-data" in Ihrem Formular.

<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
});

Falls du ein text-only mehrteiliges Formular bearbeiten musst, solltest du die .none() Methode verwenden:

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
});

Hier ist ein Beispiel dafür, wie Multer in einem HTML-Formular verwendet wird. Achte besonders auf die Felder enctype="multipart/form-data" und 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>

Dann in Ihrer Javascript-Datei würden Sie diese Zeilen hinzufügen, um sowohl auf die Datei als auch den Körper. Es ist wichtig, dass du den Wert des Feldes name aus dem Formular in deiner Upload-Funktion benutzt. Dies teilt dem Multer mit, in welchem Feld er nach den Dateien suchen soll. Wenn diese Felder im HTML-Formular und auf Ihrem Server nicht identisch sind, wird Ihr Upload fehlschlagen:

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

Dateiinformation

Jede Datei enthält folgende Informationen:

SchlüsselBeschreibungNotiz
fieldnameFeldname im Formular angegeben
originalnameName of the file on the user’s computer, or the full path when preservePath: true
encodingKodierungstyp der Datei
mimetypeMime-Typ der Datei
sizeGröße der Datei in Bytes
destinationDer Ordner, in dem die Datei gespeichert wurdeDiskStorage
filenameDer Name der Datei innerhalb des destinationDiskStorage
pathDer vollständige Pfad zur hochgeladenen DateiDiskStorage
bufferEin Buffer der gesamten DateiMemoryStorage

multer(opts)

Multer akzeptiert ein Optionsobjekt, dessen grundlegendste die Eigenschaft dest ist, die Multer anweist, wo die Dateien hochgeladen werden sollen. Falls Sie das Optionsobjekt weglassen, werden die Dateien im Speicher gespeichert und nie auf die Festplatte geschrieben.

Standardmäßig wird Multer die Dateien umbenennen, um Konflikte zu vermeiden. Die Umbenennungsfunktion kann an Ihre Bedürfnisse angepasst werden.

Die folgenden Optionen können an Multer übergeben werden.

SchlüsselBeschreibung
defCharsetDefault character set to use for text field values that do not declare one. Default: 'utf8'
defParamCharsetStandardzeichensatz für Werte von Bauteilheader-Parametern (z.B. Dateiname), die keine erweiterten Parameter sind (welche einen expliziten Zeichensatz enthalten). Standard: 'latin1'
dest oder storageWo die Dateien gespeichert werden sollen
fileFilterFunktion, um zu kontrollieren, welche Dateien akzeptiert werden
fileHwmhighWaterMark of each file stream (file.stream). Default: busboy’s default
highWaterMarkhighWaterMark of the multipart parser stream. Default: busboy’s default
limitsGrenzen der hochgeladenen Daten
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)

In einer durchschnittlichen Web-App könnte nur dest erforderlich sein, und konfiguriert werden, wie in das folgende Beispiel.

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.

Wenn du mehr Kontrolle über deine Uploads haben möchtest, möchtest du die Option storage anstelle von dest verwenden. Multerschiffe mit Speichermotoren DiskStorage und MemoryStorage; Weitere Motoren sind von Dritten erhältlich.

.single(fieldname)

Akzeptieren Sie eine einzelne Datei mit dem Namen fieldname. Die einzelne Datei wird in req.file gespeichert.

.array(fieldname[, maxCount])

Akzeptieren Sie ein Array von Dateien, alle mit dem Namen fieldname. Optionaler Fehler wenn mehr als maxCount-Dateien hochgeladen werden. Das Array der Dateien wird in req.files gespeichert.

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

.fields(fields)

Akzeptieren Sie einen Mix von Dateien, angegeben durch fields. Ein Objekt mit Arrays von Dateien wird in req.files gespeichert.

fields sollte ein Array von Objekten mit name und optional ein maxCount sein. Beispiel:

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

.none()

Nur Textfelder akzeptieren. If any file upload is made, error with code LIMIT_UNEXPECTED_FILE will be issued.

.any()

Accepts all files that come over the wire. Ein Array von Dateien wird in req.files gespeichert.

WARNUNG: Stellen Sie sicher, dass Sie immer die Dateien behandeln, die ein Benutzer hochlädt. Fügen Sie Multer nie als globale Middleware hinzu, da ein böswilliger Benutzer Dateien zu einer Route hochladen konnte, die Sie nicht erwartet haben. Verwenden Sie diese Funktion nur auf Routen , wo Sie die hochgeladenen Dateien behandeln.

storage

DiskStorage

Die Festplattenspeicher-Engine gibt Ihnen die volle Kontrolle über die Speicherung von Dateien auf der Festplatte.

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 wird verwendet, um festzustellen, in welchem Ordner die hochgeladenen Dateien gespeichert werden sollen. Dies kann auch als string angegeben werden (z.B. '/tmp/uploads'). Wenn kein destination angegeben wird, wird das Standardverzeichnis des Betriebssystems für temporäre Dateien verwendet.

Hinweis: Du bist für das Erstellen des Verzeichnisses verantwortlich, wenn du destination als Funktion bereitstellst. Wenn Sie einen String übergeben, wird der Multer sicherstellen, dass das Verzeichnis für Sie erstellt wird.

filename wird verwendet, um zu bestimmen, welche Datei im Ordner benannt werden soll. Wenn kein Dateiname angegeben wird, erhält jede Datei einen zufälligen Namen, der keine Dateiendung enthält.

Hinweis: Multer wird keine Dateiendung für Sie anhängen, Ihre Funktion sollte einen Dateinamen mit einer Dateiendung zurückgeben.

Jede Funktion wird sowohl die Anfrage (req) als auch einige Informationen über die Datei (file) übergeben, um die Entscheidung zu unterstützen.

Beachte, dass req.body möglicherweise noch nicht vollständig besiedelt ist. Es hängt von der Reihenfolge ab, dass der Client Felder und Dateien an den Server überträgt.

Um die im Callback verwendete Aufrufkonvention zu verstehen (muss Null als erster Parameter übergeben werden), lesen Sie bitte Node.js Fehlerbehandlung

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.

MemoryStorage

Die Speicher-Engine speichert die Dateien im Speicher als Buffer Objekte. Es hat keine Optionen.

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

Wenn Sie Speicher verwenden, enthält die Datei-Info ein Feld mit dem Namen buffer, das die gesamte Datei enthält.

WARNUNG: Hochladen sehr großer Dateien oder relativ kleiner Dateien in großen -Zahlen sehr schnell kann dazu führen, dass Ihre Anwendung bei Verwendung des Arbeitsspeichers nicht mehr genügend Speicher hat.

limits

Ein Objekt, das die Größengrenzen der folgenden optionalen Eigenschaften angibt. 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.

Die folgenden Ganzzahlwerte sind verfügbar:

SchlüsselBeschreibungStandard
fieldNameSizeMax. FeldnamensgrößeUnendlichkeit
fieldSizeMaximale Feldwertgröße (in Bytes)1MB
fieldsMaximale Anzahl von Nicht-DateifeldernUnendlichkeit
fileSizeFür mehrteilige Formulare ist die maximale Dateigröße (in Bytes)Unendlichkeit
filesFür mehrteilige Formulare ist die maximale Anzahl von DateifeldernUnendlichkeit
partsFür mehrteilige Formulare ist die maximale Anzahl von Teilen (Felder + Dateien)Unendlichkeit
headerPairsBei mehrteiligen Formularen ist die maximale Anzahl der Kopfzeilen-Schlüssel=>Werte-Paare zum Parsen2000
fieldNestingDepthMax number of nesting levels for field names (e.g. a[b][c] has 2 levels)Unendlichkeit
fieldArrayIndexLimitMax numeric array index accepted inside a field name (e.g. a[3] uses index 3)Unendlichkeit

Die Angabe der Grenzwerte kann dazu beitragen, Ihre Website vor Denial of Service (DoS) Attacken zu schützen.

fileFilter

Setze dies auf eine Funktion um zu kontrollieren, welche Dateien hochgeladen werden sollen und welche übersprungen werden soll. Die Funktion sollte so aussehen:

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])

Fehlerbehandlung

Wenn ein Fehler auftritt, wird Multer den Fehler an Express übertragen. Du kannst eine schöne Fehlerseite anzeigen, indem du den Standard-Express-Weg.

Wenn Sie Fehler speziell von Multer auffangen möchten, können Sie die Middleware-Funktion selbst aufrufen. Außerdem, wenn du nur [die Multer-Fehler] fangen möchtest (https://github.com/expressjs/multer/blob/main/lib/multer-error.js), du kannst die MulterError Klasse verwenden, die an das multer Objekt selbst angeschlossen ist (z. B. 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.
});
});

Eigene Speicher-Engine

Informationen zum Aufbau Ihrer eigenen Speicher-Engine finden Sie unter Multer Storage Engine.

Lizenz

MIT