Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Multipart no Node.js

Atualizado em: 8 de outubro de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

multipart/form-data é usado para enviar arquivos e campos no mesmo request. Em Node.js, o parser precisa trabalhar em streaming, aplicar limites antes de acumular dados e tratar cada parte como entrada não confiável.

Por que não usar express.json

JSON não transporta arquivos binários de forma eficiente. Base64 aumenta o tamanho e exige memória. Multipart separa partes e permite processar streams.

Busboy

npm install busboy
import Busboy from 'busboy';

app.post('/uploads', requireAuth, (req, res, next) => {
  const busboy = Busboy({
    headers: req.headers,
    limits: {
      files: 1,
      fileSize: 10 * 1024 * 1024,
      fields: 10,
      fieldSize: 16 * 1024,
      parts: 20,
    },
  });

  req.pipe(busboy);
});

Processando arquivo

busboy.on('file', (name, file, info) => {
  const { filename, mimeType } = info;
  const id = crypto.randomUUID();
  const destination = createPrivateUploadStream(id);

  file.on('limit', () => {
    destination.destroy(new Error('Arquivo excede o limite'));
  });

  file.pipe(destination);
});

Não use filename como caminho. MimeType é declaração do cliente e precisa ser verificado pelo conteúdo.

Campos

const fields = {};

busboy.on('field', (name, value, info) => {
  if (!ALLOWED_FIELDS.has(name)) return;
  fields[name] = value;
});

Limite tamanho e quantidade. Valide com JSON Schema ou Zod após o parsing.

Ordem das partes

O cliente pode enviar arquivo antes dos campos. Não dependa de ordem. Se uma decisão de autorização depende de um campo, prefira colocá-la na URL, identidade ou uma etapa anterior.

Backpressure

Use pipeline para respeitar o consumidor:

await pipeline(file, transform, destination, { signal });

Não processe chunks com listeners que iniciam tarefas ilimitadas.

Finalização

Responda somente depois que parser e streams concluírem. Controle promises de cada arquivo:

const tasks = [];

busboy.on('file', (name, file) => {
  tasks.push(storeFile(file));
});

busboy.on('close', async () => {
  try {
    const uploads = await Promise.all(tasks);
    res.status(201).json({ uploads });
  } catch (error) {
    next(error);
  }
});

Falhas parciais

Se um de vários arquivos falha, decida se toda a operação é rejeitada. Exclua objetos já gravados ou marque-os como órfãos para limpeza.

Abortamento

Quando o cliente desconecta:

const controller = new AbortController();
req.once('aborted', () => controller.abort());
req.once('close', () => {
  if (!res.writableEnded) controller.abort();
});

Propague o signal para storage e scanners.

Content-Type

O boundary vem no header. Não construa parser com boundary fornecido em outro campo. Capture erros de header inválido e retorne 400.

Limites em múltiplas camadas

Configure body size no CDN, proxy, ingress e aplicação. Valores incompatíveis geram resets difíceis de diagnosticar.

Upload direto ao object storage

Para arquivos grandes, o backend pode gerar URL pré-assinada. O cliente envia direto e depois confirma metadados. Ainda é preciso validar tamanho, tipo, autorização e status do objeto antes de disponibilizar.

Multipart upload do storage

Não confunda HTTP multipart/form-data com multipart upload de S3. O segundo divide um objeto grande em partes e exige conclusão ou abort para evitar custos de partes abandonadas.

Checksums

Calcule hash durante o stream para integridade e deduplicação controlada:

const hash = crypto.createHash('sha256');
file.on('data', (chunk) => hash.update(chunk));

Não use hash como autorização e considere ataques de deduplicação que revelam existência de arquivos.

Campos JSON em multipart

Um campo pode conter JSON, mas limite tamanho e faça parse em try/catch. Em contratos complexos, pode ser melhor criar o recurso em JSON e enviar o arquivo em endpoint separado.

Multer

Multer é popular e pode armazenar em memória ou disco. Evite memoryStorage para arquivos grandes. Configure limits, fileFilter e um storage que gere nomes seguros.

Segurança do parser

Mantenha a biblioteca atualizada. Parsers de multipart enfrentam casos extremos de boundaries, headers e partes malformadas. Teste payloads truncados e muitos campos.

CSRF e CORS

Formulários multipart podem ser enviados cross-site. Se a autenticação usa cookies, exija token CSRF e valide Origin.

Observabilidade

Meça bytes, duração, abortos, limites excedidos, falhas de storage, partes e scanner. Não use filename como label de métrica.

Erros comuns

  • bufferizar arquivo inteiro;
  • confiar no filename;
  • sem limite de fields ou parts;
  • responder antes das streams;
  • ignorar cliente desconectado;
  • não limpar uploads parciais;
  • confiar em mimetype;
  • memoryStorage em produção;
  • depender da ordem;
  • sem CSRF.

Fluxo recomendado

  1. autorize antes do body;
  2. configure limits;
  3. processe em streaming;
  4. gere ID interno;
  5. valide campos;
  6. detecte tipo real;
  7. propague cancelamento;
  8. aguarde todas as partes;
  9. compense falhas;
  10. monitore volume.

Combine Multipart com Upload Seguro de Arquivos, Streams e Backpressure, AbortController, JSON Schema e CSRF.

Consulte a documentação do Busboy e a referência HTTP da MDN.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita