Skip to content

Instantly share code, notes, and snippets.

@nicolas-oliveira
Last active June 30, 2020 17:36
Show Gist options
  • Save nicolas-oliveira/43b6a2d6b3654e9fab9697ab6b2d0b0d to your computer and use it in GitHub Desktop.
Save nicolas-oliveira/43b6a2d6b3654e9fab9697ab6b2d0b0d to your computer and use it in GitHub Desktop.
Tradução livre da documentação do Multer: https://www.npmjs.com/package/multer

Multer

Índice


Multer é um middleware node.js para manipulação de dados multipart/form-data, que é usado principalmente para o upload de arquivos. Ele é escrito em cima do busboy para máxima performace da aplicação.

NOTA: O Multer não processa nenhum formulário que não seja multiparte (multipart/form-data).

Instalação

$ npm install --save multer

Uso

Multer adiciona um objeto body e um objeto file ou files para o objeto request. O body contém os valores dos campos de texto do formulário, o file ou files contém os arquivos carregados 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>
var express = require('express')
var multer  = require('multer')
var upload = multer({ dest: 'uploads/' })
 
var app = express()
 
app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req.file é o arquivo de `avatar`
  // req.body irá segurar o campo dos dados se caso existir
})
 
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
  // req.files é o array de arquivos de `photos` 
  // req.body irá conter os campos de texto se caso existir
})
 
var cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
  // req.files é um objeto (String -> Array) onde o campo é a chave e o valor é o array de arquivos
  //
  // Por exemplo:
  //  req.files['avatar'][0] -> Arquivo
  //  req.files['gallery'] -> Array
  //
  // req.body irá conter o campo de textos se caso existir
})

Caso você precise lidar com um formulário somente de texto em várias partes, você deve usar o método .none():

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

API

Informações do arquivo

Key Description Note
fieldname Nome do campo especificado no formulário
originalname Nome do arquivo original oriundo do usuário
encoding Tipo de codificação do arquivo
mimetype Tipo de mídia do arquivo
size Tamanho do arquivo em bytes
destination A pasta em que o arquivo foi salvo DiskStorage
filename O nome do arquivo dentro do destino DiskStorage
path O caminho completo para o arquivo carregado DiskStorage
buffer Um buffer de todo o arquivo MemoryStorage

multer(opts)

Multer aceita um objeto opcional, o mais básico dos quais é a propriedade dest, que diz ao Multer onde carregar os arquivos. Caso você omitir o objeto options, os arquivos serão guardados na memória e nunca serão gravados no disco.

Por padrão, Multer irá renomear os arquivos de forma a evitar conflitos de nomes. A função de renomeamento pode ser personalizada de acordo com as suas necessidades.

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

Key Description
dest ou storage Local de armazenamento dos arquivos
fileFilter Função que irá controlar onde os arquivos são aceitos
limits Limite dos dados de upload
preservePath Mantenha o caminho dos arquivos completo invés de usar apenas o nome original

Em um aplicativo web médio, somente dest pode ser necessário, e configurado como mostrado no exemplo a seguir:

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

Se você quer mais controle sobre seus uploads, você pode usar a opção de armazenamento (storage) em vez de destino (dest). Multer fornece os motores de armazenamento DiskStorage e MemoryStorage; Mais motores estão disponíveis a partir de terceiros.


.single(fieldname)

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


.array(fieldname[, maxCount])

Aceita um conjunto de arquivos, todos com o nome de fieldname. Se o número de arquivos forem maiores do que maxCount um erro opcional irá notificá-lo. O array de arquivos será armazenado em req.files.


.fields(fields)

Aceita arquivos variados, especificada em fields. Um objeto com array de arquivos será armazenado em `req.files'.

Os fields devem ser um conjunto de objetos com name e, opcionalmente, maxCount. Exemplo:

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

.none()

Aceita apenas campos de texto. Se qualquer upload de arquivo for feito, será emitido um erro com o código "LIMIT_UNEXPECTED_FILE".


.any()

Aceita todos os arquivos que chegam pelo sistema. Um array de arquivos será armazenado em req.files. AVISO: Certifique-se de que você sempre lida com os arquivos que um usuário carrega. Nunca adicione o Multer como um middleware global, pois um usuário malicioso poderia fazer upload de arquivos para uma rota que você não antecipou. Use esta função apenas em rotas onde você esteja manipulando os arquivos carregados.


storage

DiskStorage

O DiskStorage lhe dará controle total sobre o armazenamento dos arquivos no disco.

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, '/tmp/my-uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now())
  }
})
 
var upload = multer({ storage: storage })

Existem duas opções disponíveis, destination e filename. Ambas são funções que determinam onde o arquivo deve ser armazenado.

destination é usado para determinar em que pasta os arquivos carregados devem ser armazenados. Pode também ser especificado como uma string (por exemplo, '/tmp/uploads'). Se nenhum destino for especificado, será usado o diretório padrão do sistema operacional para arquivos temporários.

Nota: Você é responsável pela criação do diretório ao fornecer o destino (destination) como uma função. Ao passar uma string, o Multer irá certificar-se de que o diretório foi criado.

filename é usado para determinar o nome do arquivo dentro da pasta. Se nenhum nome de arquivo for dado, cada arquivo receberá um nome aleatório que não inclui nenhuma extensão de arquivo.

Nota: O Multer não anexa nenhuma extenção do arquivo para você, nesse caso, sua função é retornar o nome do arquivo completo com a extenção do arquivo.

Cada função é aprovada pelos dois, a requisição (req) e alguma informação sobre o arquivo (file) para ajudar com a decisão.

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

MemoryStorage

O MemoryStorage armazena os arquivos na memória como Buffer objects (Memória temporária). Não há opções nesta função.

var storage = multer.memoryStorage()
var upload = multer({ storage: storage })

Ao utilizar armazenamento de memória, a informação do arquivo conterá um campo nomeado buffer que contém o arquivo inteiro.

AVISO: Carregar arquivos muito grandes, ou arquivos relativamente pequenos em grandes números muito rapidamente, pode fazer com que a sua aplicação fique sem memória quando o armazenamento de memória é utilizado.

limits

Um objeto especificando os limites de tamanho das seguintes propriedades opcionais. Multer passa este objeto diretamente para o busboy, e os detalhes das propriedades podem ser encontrados na página do busboy.

Estão disponíveis os seguintes valores inteiros:

Key Description Default
fieldNameSize Tamanho máximo do nome 100 bytes
fieldSize Tamanho máximo do valor do campo (em bytes) 1MB
fields Número máximo dos campos que não são arquivos Infinity
fileSize Para formulários com várias partes, o tamanho máximo do arquivo (em bytes) Infinity
files Para formulários com várias partes, o número máximo de campo dos arquivos Infinity
parts Para formulários com várias partes, o número máximo de partes (campos + arquivos) Infinity
headerPairs Para formulários com várias partes, o número máximo do header chave=>valor que serão transformados 2000

A especificação dos limites pode ajudar a proteger o seu site contra ataques de negação de serviço (DoS).

fileFilter

Defina esta função para controlar quais os arquivos que devem ser carregados e quais os que devem ser ignorados. A função deve ter este aspecto:

function fileFilter (req, file, cb) {
 
  // A função deve chamar `cb` com um booleano
  // para indicar se o arquivo deve ser aceito
 
  // Para rejeitar este arquivo passe `false`, por exemplo:
  cb(null, false)
 
  // Para aceitar o arquivo passe `true`, por exemplo:
  cb(null, true)
 
  //  Pode-se sempre passar caso algo indesejado aconteça:
  cb(new Error('I don\'t have a clue!'))
 
}

Tratamento de erros

Ao encontrar um erro, Multer delegará o erro para o Express. Uma boa forma de exibir uma página de erro é utilizando a forma padrão do Express.

Se quiser tratar erros específicos do Multer, você mesmo pode chamar a função como middleware. Além disso, você pode verificar apenas os erros do Multer aqui, podendo usar a classe MulterError que está ligada ao próprio objeto Multer (por exemplo, err instanceof multer.MulterError).

var multer = require('multer')
var upload = multer().single('avatar')
 
app.post('/profile', function (req, res) {
  upload(req, res, function (err) {
    if (err instanceof multer.MulterError) {
      // Ocorreu um erro ao fazer o upload para o Multer.
    } else if (err) {
      // Ocorreu um erro desconhecido ao fazer o upload.
    }
 
    // Tudo correu bem.
  })
})

storage engine personalizado

Para mais informações sobre como construir o seu próprio motor de armazenamento, veja Multer Storage Engine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment