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

MIMEType no Node.js: valide Content-Type com segurança

Atualizado em: 21 de outubro de 2026

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

O MIMEType no Node.js ajuda a interpretar, validar e normalizar tipos de mídia como application/json, text/html; charset=utf-8 e multipart/form-data. Em aplicações web, esse dado aparece em requisições, respostas, uploads, APIs, e-mails e integrações entre serviços. Tratar o valor como uma string comum costuma gerar comparações frágeis, bugs com parâmetros e decisões de segurança incorretas.

A classe MIMEType, disponível em node:util, oferece uma representação estruturada com tipo, subtipo, essência e parâmetros. Isso facilita separar text de html, ler charset, normalizar capitalização e serializar o valor novamente de forma consistente.

Neste guia, você aprenderá a usar MIMEType e MIMEParams, validar Content-Type, tratar uploads, negociar respostas, evitar confusão entre extensão e conteúdo real, criar allowlists e testar cenários de segurança.

Importando MIMEType

import { MIMEType } from 'node:util';

Em CommonJS:

const { MIMEType } = require('node:util');

A documentação oficial está na classe MIMEType do Node.js. A API segue o modelo WHATWG e oferece parsing consistente para tipos de mídia.

Criando uma instância

const mime = new MIMEType('text/html; charset=UTF-8');

console.log(mime.type);      // text
console.log(mime.subtype);   // html
console.log(mime.essence);   // text/html
console.log(mime.params.get('charset')); // UTF-8

A propriedade essence contém apenas tipo e subtipo. Ela é útil quando os parâmetros não devem influenciar a decisão principal.

Normalização

const mime = new MIMEType('Application/JSON; Charset=utf-8');
console.log(mime.essence); // application/json
console.log(mime.toString());

Comparar strings manualmente falha quando há espaços, capitalização diferente ou parâmetros adicionais. A classe centraliza essa normalização.

Validando Content-Type

function requireJson(contentType) {
  if (!contentType) {
    throw new Error('Content-Type ausente');
  }

  const mime = new MIMEType(contentType);

  if (mime.essence !== 'application/json') {
    throw new Error('Content-Type deve ser application/json');
  }

  return mime;
}

Em uma API, valide o cabeçalho antes de ler e interpretar o corpo. Isso reduz ambiguidade e evita que payloads inesperados cheguem ao parser.

Para estruturar respostas de erro, consulte Problem Details no Node.js.

JSON com sufixo +json

Vários formatos usam subtipos como application/problem+json ou application/merge-patch+json. Uma validação útil pode aceitar o formato principal e sufixos padronizados:

function isJsonMime(value) {
  const mime = new MIMEType(value);
  return mime.essence === 'application/json' ||
    mime.subtype.endsWith('+json');
}

Não aceite qualquer subtipo apenas porque termina com json. Use o sufixo estruturado +json e uma allowlist quando a operação exigir um contrato específico.

Parâmetros com MIMEParams

const mime = new MIMEType('text/plain; charset=utf-8; format=flowed');

for (const [name, value] of mime.params) {
  console.log(name, value);
}

Você também pode alterar parâmetros:

mime.params.set('charset', 'utf-8');
mime.params.delete('format');
console.log(mime.toString());

Não use parâmetros arbitrários enviados pelo cliente para tomar decisões sensíveis sem validação.

Charset

Para texto, o charset define como bytes viram caracteres. Mesmo que UTF-8 seja o padrão de muitas APIs modernas, não suponha que todo conteúdo recebido está em UTF-8 quando o protocolo permite outros valores.

function getCharset(contentType) {
  const mime = new MIMEType(contentType);
  return mime.params.get('charset')?.toLowerCase() ?? null;
}

Ao responder JSON, use um cabeçalho claro:

res.setHeader('Content-Type', 'application/json; charset=utf-8');

Uploads de arquivos

O Content-Type de um upload é informado pelo cliente e não prova o conteúdo real. Um arquivo executável pode ser enviado como image/png. Use MIMEType para parsing e política inicial, mas valide também assinatura binária, tamanho, extensão permitida e comportamento do arquivo.

Veja Upload Seguro de Arquivos no Node.js e Multipart no Node.js.

Allowlist de tipos

const allowed = new Set([
  'image/png',
  'image/jpeg',
  'application/pdf'
]);

function validateUploadType(value) {
  const mime = new MIMEType(value);

  if (!allowed.has(mime.essence)) {
    throw new Error('Tipo de arquivo não permitido');
  }

  return mime;
}

Prefira allowlist. Bloquear apenas tipos conhecidos como perigosos deixa passar formatos inesperados.

Respostas HTTP

Ao servir arquivos, defina Content-Type explicitamente e adicione proteções contra interpretação indevida:

res.setHeader('Content-Type', mime.toString());
res.setHeader('X-Content-Type-Options', 'nosniff');

O cabeçalho nosniff reduz a chance de navegadores tentarem interpretar o conteúdo de forma diferente do tipo declarado.

Negociação com Accept

O cabeçalho Accept pode conter vários valores, pesos e wildcards. MIMEType interpreta um tipo individual, mas não é um parser completo de negociação HTTP. Para Accept complexo, use uma biblioteca confiável ou implemente uma política restrita.

function chooseResponse(accept) {
  if (!accept || accept.includes('application/json')) {
    return 'application/json';
  }

  if (accept.includes('text/plain')) {
    return 'text/plain';
  }

  return null;
}

Não reutilize diretamente valores de Accept como Content-Type da resposta.

MIME e extensão

Extensão e MIME resolvem problemas diferentes. A extensão ajuda a identificar convenção de nome; o MIME descreve o formato declarado. Nenhum dos dois substitui inspeção real quando segurança importa.

const fileName = 'relatorio.pdf';
const declared = new MIMEType('application/pdf');

Uma política robusta compara extensão permitida, MIME declarado e assinatura real.

Content-Type ausente

Em endpoints que exigem corpo estruturado, rejeite o cabeçalho ausente. Em downloads legados, pode ser necessário usar application/octet-stream.

res.setHeader('Content-Type', 'application/octet-stream');
res.setHeader('Content-Disposition', 'attachment; filename="arquivo.bin"');

Tratando erros de parsing

function parseMime(value) {
  try {
    return new MIMEType(value);
  } catch {
    return null;
  }
}

Não exponha stack trace ao cliente. Registre o valor de forma limitada e redigida quando ele puder conter dados inesperados.

Integração com fetch

const response = await fetch(url);
const contentType = response.headers.get('content-type');

if (!contentType) {
  throw new Error('Resposta sem Content-Type');
}

const mime = new MIMEType(contentType);

if (!isJsonMime(mime.toString())) {
  throw new Error(`Formato inesperado: ${mime.essence}`);
}

const data = await response.json();

Validar antes de chamar response.json() produz erros melhores e evita tentar interpretar HTML de proxy como JSON.

Veja Fetch no Node.js e Undici no Node.js.

APIs de webhook

Webhooks frequentemente usam application/json, mas alguns provedores enviam application/x-www-form-urlencoded. Valide o tipo antes de selecionar o parser e mantenha a verificação de assinatura sobre os bytes originais quando o protocolo exigir.

Cache e Vary

Quando a resposta muda com base no formato aceito, inclua Vary: Accept para evitar que caches entreguem representação errada.

res.setHeader('Vary', 'Accept');

Consulte ETag e Cache HTTP no Node.js.

Testes

import test from 'node:test';
import assert from 'node:assert/strict';
import { MIMEType } from 'node:util';

test('normaliza application/json', () => {
  const mime = new MIMEType('Application/JSON; Charset=UTF-8');
  assert.equal(mime.essence, 'application/json');
  assert.equal(mime.params.get('charset'), 'UTF-8');
});

Inclua casos inválidos, parâmetros duplicados, espaços, capitalização, tipos com sufixo e cabeçalhos ausentes.

Erros comuns

  • comparar Content-Type por igualdade de string;
  • esquecer parâmetros como charset;
  • confiar no MIME enviado pelo usuário;
  • usar blocklist em vez de allowlist;
  • aceitar qualquer subtype terminado em json;
  • servir conteúdo sem nosniff;
  • usar Accept diretamente na resposta;
  • não testar valores malformados.

Checklist

  • parse com MIMEType;
  • compare pela essence;
  • valide parâmetros necessários;
  • use allowlist;
  • inspecione assinatura de uploads;
  • defina Content-Type na resposta;
  • adicione nosniff;
  • trate erros sem vazar detalhes;
  • teste formatos alternativos;
  • monitore rejeições.

Conclusão

O MIMEType no Node.js oferece uma forma estruturada de lidar com tipos de mídia. Em vez de manipular cabeçalhos como strings frágeis, a aplicação separa tipo, subtipo, essência e parâmetros de maneira consistente.

Use a classe para validar APIs, interpretar respostas e aplicar políticas de upload, mas lembre que MIME declarado não prova o conteúdo real. Combine parsing, allowlist, inspeção binária e cabeçalhos seguros para obter um fluxo confiável.

Como referência complementar, consulte o registro de tipos de mídia da IANA.

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