Módulo http
O módulo http do Node.js é nativo e permite criar servidores web e consumir APIs HTTP. Ele expõe métodos e classes para manipulação direta de pedidos e respostas, utilizando streams para leitura/escrita eficiente e eventos para controle assíncrono.
Servidor HTTP básico
Um servidor de http é criado com o método cresteServer() do módulo http.
Exemplo simples de servidor:
const http = require('http');
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200; // Define código de status
res.setHeader('Content-Type', 'text/plain'); // Define cabeçalho
res.end('Olá Mundo!\n'); // Finaliza resposta
});
server.listen(port);
- O método
http.createServerrecebe uma função callback com dois parâmetros:- req: objeto de pedido (request)
- res: objeto de resposta (response)
O objeto request (req)
O request (req) é uma instância da classe http.IncomingMessage. Representa todos os dados do pedido feito pelo cliente ao servidor:
req.method: Método HTTP (GET,POSTetc.)req.url: Caminho/rota requisitadareq.headers: Objeto com todos os cabeçalhos enviadosreq.on('data', callback): Evento para ler partes do corpo do pedido (stream)req.on('end', callback): Evento disparado ao final da leitura
Exemplo de acesso aos dados:
const server = http.createServer((req, res) => {
console.log(`Método: ${req.method}`);
console.log(`URL: ${req.url}`);
let body = '';
req.on('data', chunk => {
body += chunk.toString(); // Acumulando corpo recebido
});
req.on('end', () => {
console.log(`Corpo: ${body}`);
res.end('Pedido processado\n');
});
});
- Ideal para manipular POST, PUT e métodos que enviam dados no pedido.
O objeto response (res)
O response (res) é uma instância de http.ServerResponse. Permite definir status, cabeçalhos e corpo da resposta enviada ao cliente:
res.statusCode: Define o código HTTP de status (ex: 200, 404)res.setHeader(nome, valor): Configura cabeçalhos HTTP (ex:Content-Type)res.write(data): Envia dados para o corpo da resposta em partes (stream, opcional). Pode ser usado várias vezes.res.end([data]): Finaliza a resposta e envia tudo ao cliente (pode incluir dados finais)res.writeHead(statusCode, [headers]): Atalho para definir código de status e vários cabeçalhos juntosres.headersSent: Indica se os cabeçalhos já foram enviados ao cliente- Manipulação de headers: getHeader, hasHeader, removeHeader.
Exemplo básico de manipulação:
res.statusCode = 404;
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify({ error: 'Não encontrado' }));
res.end();
Estrutura resumida do ciclo pedido-resposta
- O Node recebe o pedido e instancia
reqeres - O servidor inspeciona e lê dados via
req - Define resposta via propriedades e métodos de
res - Envia resposta ao cliente com
res.end()
O método write()
O método write() do objeto response, envia um pedaço de dados para o corpo da resposta. Pode ser chamado múltiplas vezes para enviar dados em pedaços (streaming).
Sintaxe:
response.write([data[, encoding]][, callback])
Exemplo:
res.write('Parte do conteúdo');
O método end()
O método end() do objeto response serve para sinalizar o servidor acabou de enviar a resposta. Este método é fundamental e obrigatório para terminar o ciclo pedido/resposta.
Sintaxe:
response.end([data[, encoding]][, callback])
- data: Bloco de dados opcional a ser enviado na resposta.
- encoding: Codificação opcional(defeito: ‘utf8’).
- callback: Função de callback opcional a ser chamada quando a resposta termina.
Exemplo com res.write() e res.end():
const http = require('http');
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.write('Olá, ');
res.write('mundo!');
res.end(); // Finaliza e envia a resposta
});
server.listen(3000);
Cabeçalhos da resposta
Os cabeçalhos na resposta a um pedido HTTP são essenciais para fornecer informações cruciais ao cliente sobre como interpretar, processar e tratar o conteúdo recebido. Eles atuam como metadados que acompanham o corpo da mensagem e garantem que a comunicação entre cliente e servidor ocorra de forma eficiente, segura e correta.
Importância dos cabeçalhos na resposta HTTP
- Informação sobre o conteúdo: Cabeçalhos como
Content-Typeindicam o tipo de dado enviado (HTML, JSON, imagem, etc.), permitindo que o cliente saiba como mostrar ou utilizar o conteúdo recebido. - Controle de cache: Cabeçalhos como
Cache-Controlorientam o cliente sobre o armazenamento temporário do conteúdo, reduzindo o tráfego e aumentando a velocidade em requisições futuras. - Controle da conexão: Indicadores como
Connectiondefinem se a conexão será mantida aberta para múltiplos pedidos ou fechada após a resposta. - Segurança: Cabeçalhos específicos definem políticas de segurança, como restrições de compartilhamento entre origens diferentes (CORS) e prevenção de ataques (exemplo:
Strict-Transport-Security). - Autenticação e estados: Alguns cabeçalhos tratam de autenticação (
WWW-Authenticate) e controle de sessão via cookies. - Tamanho do conteúdo: Cabeçalhos como
Content-Lengthinformam o tamanho dos dados para que o cliente saiba quando a transferência terminou.
Sem esses cabeçalhos, o cliente poderia não interpretar corretamente a resposta, gerando problemas de apresentação, falhas na reutilização de recursos ou até vulnerabilidades de segurança. Eles garantem que a comunicação HTTP seja padronizada, compreensível e ajustada ao contexto de cada pedidoo e resposta.
Assim, enviar cabeçalhos adequados é fundamental para a interoperabilidade, desempenho e segurança da aplicação web.
O método setHeader()
O método principal para definir individualmente, cabeçalhos na resposta é o método setHeader() do objeto response.
Sintaxe:
res.setHeader(nomeDoCabecalho, valorDoCabecalho);
nomeDoCabecalho: String com o nome do cabeçalho (exemplo:"Content-Type")valorDoCabecalho: Valor do cabeçalho (exemplo:"text/html")
O método setHeader() pode ser chamado várias vezes para configurar diferentes cabeçalhos antes que a resposta seja enviada.
Exemplo:
const server = http.createServer((req, res) => {
// Definindo múltiplos cabeçalhos individualmente
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Powered-By', 'Node.js');
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
res.writeHead(200); // enviando status 200 OK
res.end('<h1>Exemplo com múltiplos cabeçalhos usando setHeader()</h1>');
});
O método writeHeader()
O método writeHeader() envia ao cliente o status HTTP da resposta junto com os cabeçalhos. Além disso, writeHead() aceita como parâmetros o código de status, uma mensagem opcional e um objeto com vários cabeçalhos, permitindo enviar tudo de uma vez. Quando writeHead() é chamado, os cabeçalhos são considerados “travados” e enviados na resposta; após isso, não se pode mais modificar os cabeçalhos.
Em resumo, setHeader() é para definir ou alterar cabeçalhos antes do envio, enquanto writeHead() envia efetivamente os cabeçalhos (e status) para o cliente, podendo também definir vários cabeçalhos juntos e o status HTTP ao mesmo tempo.
Exemplo:
const server = http.createServer((req, res) => {
// Definindo status 200 e múltiplos cabeçalhos num único método
res.writeHead(200, {
'Content-Type': 'text/html',
'X-Powered-By': 'Node.js',
'Cache-Control': 'no-cache, no-store, must-revalidate'
});
res.end('<h1>Exemplo com múltiplos cabeçalhos usando writeHead()</h1>');
});
Códigos de resposta do protocolo HTTP
Os códigos de resposta no protocolo HTTP são números de três dígitos que indicam o resultado do processamento de um pedidoo. Esses códigos estão categorizados em cinco grandes classes, conforme o valor do primeiro dígito:
- 1xx (Informativo): Indicam que a solicitação foi recebida e que o processo continua.
- Exemplos:
- 100 Continue: O servidor recebeu os cabeçalhos e o cliente pode continuar a enviar o corpo da requisição.
- 101 Switching Protocols: O servidor está mudando de protocolo conforme pedido.
- 103 Early Hints: Fornece cabeçalhos preliminares antes da resposta final.
- Exemplos:
- 2xx (Sucesso): Indicam que a solicitação foi bem-sucedida.
- Exemplos:
- 200 OK: A solicitação foi bem-sucedida e o recurso retornado.
- 201 Created: Um novo recurso foi criado após a solicitação.
- 204 No Content: A solicitação foi bem-sucedida, mas não há conteúdo para retornar.
- 206 Partial Content: Resposta a uma requisição de recurso parcial.
- Exemplos:
- 3xx (Redirecionamento): Indicam que é necessário algum tipo de redirecionamento para completar a solicitação.
- Exemplos comuns incluem 301 Moved Permanently e 302 Found.
- 4xx (Erro do Cliente): Indicam erro por parte da solicitação enviada pelo cliente.
- Exemplos:
- 400 Bad Request: Solicitação inválida.
- 401 Unauthorized: Não autorizado.
- 403 Forbidden: Proibido.
- 404 Not Found: Recurso não encontrado.
- Exemplos:
- 5xx (Erro do Servidor): Indicam falhas do servidor ao processar a solicitação.
- Exemplos:
- 500 Internal Server Error: Erro interno do servidor.
- 502 Bad Gateway: Gateway inválido.
- 503 Service Unavailable: Serviço indisponível.
- Exemplos:
Valores possiveis para o cabeçalho Content-Type
O formato de dados que vai no corpo da resposta é definido no cabeçalho pela propriedade Content-Type. Exemplos de valores são:
text/html— conteúdo HTML.text/plain— texto simples.application/json— dados no formato JSON.application/xml— XML.text/css— folhas de estilo CSS.text/javascriptouapplication/javascript— scripts JavaScript.image/jpeg,image/png,image/gif— imagens nos formatos JPEG, PNG, GIF.application/pdf— arquivos PDF.audio/mpeg— arquivos de áudio MP3.video/mp4— vídeos MP4.multipart/form-data— dados de múltiplas partes (usado por exemplo em formulários que enviam ficheiros).application/octet-stream— dados binários gerais, usado para downloads genéricos.application/x-www-form-urlencoded— dados codificados em URL (geralmente em formulários).
Além do tipo principal, o cabeçalho Content-Type pode incluir parâmetros como charset=utf-8 para indicar a codificação de caracteres.
Exemplo completo com manipulação de rota e método
const http = require("http");
const server = http.createServer((req, res) => {
if (req.method === "GET") {
if (req.url === "/") {
res.setHeader("Content-Type", "text/html; charset=utf-8"); //define cabeçalho
res.write("<h1>Bem vindos</h1>"); //escreve dados no corpo de resposta
res.end(); //envia resposta ao cliente
} else if (req.url === "/alunos") {
res.writeHeader(200, { "Content-Type": "text/html; charset=utf-8" }); //envia cabeçalhos
res.write("<h1>Alunos</h1>"); //escreve dados no corpo de resposta
res.end(); //envia resposta ao cliente
}
}
});
server.listen(3000, function () {
console.log("Servidor à escuta na porta " + 3000);
});
- O servidor examina método e caminho solicitados, e responde de acordo.
Considerações finais
- Tanto request quanto response são streams, possibilitando manipulação eficiente de dados volumosos.
- Podem ser usados para construir APIs, servidores web, proxy, entre outros.
- O controle direto desses objetos permite máxima flexibilidade, mas exige manipulação manual de fluxos e eventos.
Obter dados de um pedido GET: Ler a querystring
A querystring faz parte do url do pedido e é, basicamente, uma string com os argumentos de um pedido GET.
Por exemplo, se o pedido GET tiver o url seguinte:
http://localhost:8080/?ano=2017&mes=Julho
A querystring é a parte: ?ano=2017&mes=Julho
Esta querystring é composta por dois argumentos: ano e mes.
const http = require("http");
const url = require("url");
const port = 3000;
const server = http.createServer((req, res) => {
const urlobj = new URL(req.url, `http://${req.headers.host}`);
const nome = urlobj.searchParams.get("nome");
const morada = urlobj.searchParams.get("morada");
res.statusCode = 200; // Define código de status
res.setHeader("Content-Type", "text/plain; charset=utf-8"); // Define cabeçalho
res.write(`Nome: ${nome} `);
res.write(`Morada: ${morada} `);
res.end(); // Finaliza resposta
});
server.listen(port, function () {
console.log("Servidor à escuta na porta " + port);
});
Obter dados de um pedido POST
Para obter dados em formato JSON do corpo de um pedido POST ou PUT em Node.js, é necessário:
- Escutar os eventos de dados do objeto
requestpara capturar os pedaços de dados recebidos. - Concatenar esses pedaços até o evento de fim, que indica que o corpo da requisição foi totalmente recebido.
- Depois, converter esses dados concatenados (em string) para um objeto JSON com
JSON.parse.
Exemplo
// Importa o módulo HTTP nativo do Node.js
const http = require('http');
// Cria um servidor HTTP
const server = http.createServer((req, res) => {
// Só tratamos métodos POST e PUT que tenham um corpo JSON
if (req.method === 'POST' || req.method === 'PUT') {
let body = '';
// Escuta dados do corpo da requisição
req.on('data', chunk => {
body += chunk.toString(); // converte buffer para string e concatena
});
// Quando terminar de receber todos os dados
req.on('end', () => {
console.log('Dados recebidos:', body);
// Resposta de sucesso
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify({ message: 'Dados recebidos com sucesso', dadosRecebidos: body }));
});
} else {
// Para outros métodos apenas responder método não permitido
res.writeHead(405, {'Content-Type': 'text/plain'});
res.end('Método não permitido' );
}
});
// Servidor escutando na porta 3000
server.listen(3000, () => {
console.log('Servidor a executar na porta 3000');
});
O servidor irá imprimir o objeto JSON recebido no console e responderá com confirmação.
Esse método é o básico para manipular corpo de requisições JSON em Node.js sem frameworks adicionais, aproveitando os eventos de leitura de streams do objeto IncomingMessage recebido no callback do servidor HTTP nativo.
Enviar uma resposta em JSON
O exemplo a seguir demonstra como enviar uma resposta com dados em JSON :
var http = require('http');
var server = http.createServer(function (req, res) {
if (req.url == '/data') { //check the URL of the current request
res.writeHead(200, { 'Content-Type': 'application/json' });
res.write(JSON.stringify({ mensagem: "Olá mundo"}));
res.end();
}
});
server.listen(5000);
console.log('Node.js web server at port 5000 is running..')
O output no browser será o seguinte:
{ “mensagem”: “Olá mundo” }
