multer middleware

Multer é um middleware node.js para manipular multipart/form-data, que é usado principalmente para carregar arquivos. É escrito sobre busboy para uma eficiência máxima.

OBSERVAÇÃO: Multer não irá processar nenhum formulário que não seja multiparte (multipart/form-data).

Instalação

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

Utilização

Multer adiciona um objeto body e um objeto file ou files para o objeto request. O objeto body contém os valores dos campos de texto do formulário, o objeto arquivo ou arquivos contém os arquivos enviados através do formulário.

Exemplo de uso básico:

Não se esqueça do enctype="multipart/form-data" no seu formulário.

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

Caso você precise manipular um formato multipart apenas de texto, você deve usar o método .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
});

Aqui está um exemplo de como o multer é usado em um formulário HTML. Anote especial os campos enctype="multipart/form-data" e `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>

Então em seu arquivo javascript você adicionaria essas linhas para acessar o arquivo e o corpo. É importante que você use o valor do campo ‘nome’ do formulário em sua função de upload. Isto informa ao multer qual campo no pedido ele deve procurar pelos arquivos. Se esses campos não forem os mesmos no formulário HTML e no seu servidor, seu upload falhará:

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

Informação do arquivo

Cada arquivo contém as seguintes informações:

ChaveDescrição:Observação
nomedocampoNome do campo especificado no formulário
originalnameName of the file on the user’s computer, or the full path when preservePath: true
encoding`Tipo de codificação do arquivo
mimetypeTipo MIME do arquivo
sizeTamanho do arquivo em bytes
destinoA pasta na qual o arquivo foi salvoDiskStorage
nome_arquivoO nome do arquivo dentro do destinoDiskStorage
caminhoO caminho completo para o arquivo enviadoDiskStorage
bufferUm Buffer de todo o arquivoMemoryStorage

multer(opts)

Multer aceita um objeto de opção, o mais básico é a propriedade dest , que informa ao Multer onde fazer o upload dos arquivos. Caso você omita o objeto de opções , os arquivos serão mantidos na memória e nunca gravados no disco.

Por padrão, o Multer renomeará os arquivos para evitar a nomeação de conflitos. A função de renomeação pode ser personalizada de acordo com suas necessidades.

As seguintes são as opções que podem ser passadas para o Multer.

ChaveDescrição:
defCharsetDefault character set to use for text field values that do not declare one. Default: 'utf8'
defParamCharsetConjunto de caracteres padrão para usar para valores dos parâmetros do cabeçalho das partes (por exemplo, nome do arquivo) que não são parâmetros estendidos (que contêm um conjunto de caracteres explícito). Padrão: 'latin1'
dest ou armazenamentoOnde armazenar os arquivos
FiltroArquivoFunção para controlar quais arquivos são aceitos
fileHwmhighWaterMark of each file stream (file.stream). Default: busboy’s default
highWaterMarkhighWaterMark of the multipart parser stream. Default: busboy’s default
limitsLimites dos dados enviados
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)

Em um aplicativo web comum, apenas dest pode ser necessário e configurado como mostrado em o exemplo a seguir.

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.

Se você quer mais controle sobre seus uploads, você vai querer usar a opção storage ao invés de dest. Mergulho com motores de armazenamento DiskStorage e MemoryStorage; Mais motores estão disponíveis a partir de terceiros.

.single(fieldname)

Aceitar um único arquivo com o nome fieldname. O único arquivo será armazenado em req.file.

.array(fieldname[, maxCount])

Aceitar uma matriz de arquivos, tudo com o nome fieldname. Erro opcional se mais do que os arquivos ‘maxCount’ forem enviados. A matriz de arquivos será armazenada em 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)

Aceitar uma mistura de arquivos, especificados por ‘campos’. Um objeto com matrizes de arquivos será armazenado em req.files.

‘fields’ deve ser um array de objetos com ‘nome’ e, opcionalmente, um ‘maxCount’. Exemplo:

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

.none()

Aceitar apenas campos de texto. If any file upload is made, error with code LIMIT_UNEXPECTED_FILE will be issued.

.any()

Accepts all files that come over the wire. Um array de arquivos será armazenado em req.files.

AVISO: Certifique-se de que você sempre manipula os arquivos que um usuário envia. Nunca adicione um multer como um middleware global, já que um usuário malicioso pode enviar arquivos para uma rota que você não antecipou. Use esta função apenas em rotas onde você está manipulando os arquivos carregados.

‘armazenamento’

DiskStorage

O mecanismo de armazenamento de disco dá controle total sobre o armazenamento de arquivos.

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. Isto também pode ser dado como uma string (por exemplo, '/tmp/uploads'). Se nenhum destination for dado, o diretório padrão do sistema operacional para arquivos temporários será usado.

Nota: Você é responsável por criar o diretório ao fornecer destino como uma função. Ao passar uma string, o multer garantirá que o diretório é criado para você.

nome do arquivo é usado para determinar qual arquivo deve ser nomeado dentro da pasta. If no filename is given, each file will be given a random name that doesn’t include any file extension.

Nota: Multer não irá acrescentar nenhuma extensão de arquivo para você, sua função deve retornar um nome de arquivo completo com uma extensão de arquivo.

Cada função é passada tanto a solicitação (req) quanto algumas informações sobre o arquivo (arquivo) para auxiliar na decisão.

Note que req.body pode não ter sido totalmente preenchido ainda. Depende da ordem que o cliente transmite campos e arquivos para o servidor.

Para entender a convenção de chamada usada no callback (precisa passar null como o primeiro parâmetro), consulte Node. s Erro na manipulação

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

O mecanismo de armazenamento de memória armazena os arquivos em memória como objetos Buffer. Ela não tem nenhuma opção.

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

Ao usar o armazenamento de memória, a informação dos arquivos conterá um campo chamado buffer que contém o arquivo inteiro.

AVISO: envio de arquivos muito grandes, ou arquivos relativamente pequenos em númerosformat@@0 grandes com muito rapidamente, pode fazer com que seu aplicativo fique sem memória quando armazenamento de memória for usado.

limits

Um objeto especificando os limites de tamanho das seguintes propriedades opcionais. 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.

Os seguintes valores de números inteiros estão disponíveis:

ChaveDescrição:Padrão
fieldNameSizeTamanho máximo do nome do campoInfinito
tamanhoDoCampoTamanho máximo do campo (em bytes)1MB
’campos’Número máximo de campos não-arquivoInfinito
tamanhoArquivoPara formas multipartes, o tamanho máximo do arquivo (em bytes)Infinito
arquivosPara formulários multipartes, o número máximo de campos de arquivoInfinito
peças`Para formulários multipartes, o número máximo de peças (campos + arquivos)Infinito
headerPairsPara formas de múltiplas partes, o número máximo de pares chave de cabeçalho=>valores para analisar2000
fieldNestingDepthMax number of nesting levels for field names (e.g. a[b][c] has 2 levels)Infinito
fieldArrayIndexLimitMax numeric array index accepted inside a field name (e.g. a[3] uses index 3)Infinito

Especificar os limites pode ajudar a proteger seu site contra ataques de negação de serviço (DoS).

FiltroArquivo

Defina como uma função para controlar quais arquivos devem ser carregados e quais devem ser ignorados. A função deve ficar assim:

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

Manipulação de erros

Quando encontrar um erro, Multer irá delegar o erro ao Express. Você pode exibir uma boa página de erro usando o caminho expresso padrão.

Se você quiser capturar erros especificamente do Multer, você pode chamar a função middleware de si mesmo. Além disso, se você quiser pegar apenas os erros de Multer, você pode usar a classe MulterError que está anexada ao objeto multer em si (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.
});
});

Mecanismo de armazenamento personalizado

Para obter informações sobre como construir seu próprio motor de armazenamento, veja Motor de Armazenamento de Multer.

Tipo:

MIT