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
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/multerUtilizaçã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:
| Chave | Descrição: | Observação |
|---|---|---|
nomedocampo | Nome do campo especificado no formulário | |
originalname | Name of the file on the user’s computer, or the full path when preservePath: true | |
| encoding` | Tipo de codificação do arquivo | |
mimetype | Tipo MIME do arquivo | |
size | Tamanho do arquivo em bytes | |
destino | A pasta na qual o arquivo foi salvo | DiskStorage |
nome_arquivo | O nome do arquivo dentro do destino | DiskStorage |
caminho | O caminho completo para o arquivo enviado | DiskStorage |
buffer | Um Buffer de todo o arquivo | MemoryStorage |
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.
| Chave | Descrição: |
|---|---|
defCharset | Default character set to use for text field values that do not declare one. Default: 'utf8' |
defParamCharset | Conjunto 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 armazenamento | Onde armazenar os arquivos |
FiltroArquivo | Função para controlar quais arquivos são aceitos |
fileHwm | highWaterMark of each file stream (file.stream). Default: busboy’s default |
highWaterMark | highWaterMark of the multipart parser stream. Default: busboy’s default |
limits | Limites dos dados enviados |
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) |
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:
| Chave | Descrição: | Padrão |
|---|---|---|
fieldNameSize | Tamanho máximo do nome do campo | Infinito |
tamanhoDoCampo | Tamanho máximo do campo (em bytes) | 1MB |
| ’campos’ | Número máximo de campos não-arquivo | Infinito |
tamanhoArquivo | Para formas multipartes, o tamanho máximo do arquivo (em bytes) | Infinito |
arquivos | Para formulários multipartes, o número máximo de campos de arquivo | Infinito |
| peças` | Para formulários multipartes, o número máximo de peças (campos + arquivos) | Infinito |
headerPairs | Para formas de múltiplas partes, o número máximo de pares chave de cabeçalho=>valores para analisar | 2000 |
fieldNestingDepth | Max number of nesting levels for field names (e.g. a[b][c] has 2 levels) | Infinito |
fieldArrayIndexLimit | Max 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 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])
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.