Como funciona a comunicação HTTP
Antes de nos debruçarmos sobre a definição de um cabeçalho HTTP, penso que é importante ter, pelo menos, uma visão geral de como funciona o protocolo HTTP. Como certamente já sabe, o Protocolo de Transferência de Hipertexto (HTTP) é a base sobre a qual a Web assenta atualmente. Em termos gerais, permite a transferência de informação entre um servidor e os seus clientes. O fluxo efetivo desta troca de informação é mais ou menos assim:
- O cliente abre uma nova ligação TCP
- Envia uma mensagem ao servidor, o que se denomina pedido HTTP
- O servidor recebe e interpreta o pedido
- Em seguida, envia uma mensagem de volta ao cliente, a que se denomina resposta HTTP
- O cliente lê a mensagem e continua ou encerra a ligação

O aspeto importante em que nos vamos concentrar hoje é a mensagem, em particular a mensagem enviada pelo cliente. Para que a comunicação entre o servidor e o cliente seja eficiente, as mensagens têm de ser formatadas conforme descrito pelo protocolo HTTP. No que diz respeito ao pedido HTTP, os elementos que compõem a mensagem são:
O método descreve o que pretendemos fazer com o nosso pedido (se queremos receber, enviar, atualizar informações, etc.)
- O caminho, o endereço URL ao qual estamos a tentar aceder
- A versão do protocolo HTTP que estamos a utilizar
- Os cabeçalhos HTTP, que são utilizados para enviar informações adicionais e metadados juntamente com o nosso pedido
- O corpo, caso estejamos a utilizar um método que envia informações para o servidor (como uma solicitação POST)
O que são os cabeçalhos HTTP no Axios e como funcionam?
Em termos simples, os cabeçalhos HTTP são campos que transmitem informações adicionais e metadados à mensagem. Mais uma vez, por mensagem, entendemos a solicitação quando esta é enviada pelo cliente e a resposta quando esta é enviada pelo servidor. Assim, tanto o servidor como o cliente podem passar e receber cabeçalhos. Por exemplo, digamos que queira abrir uma ligação persistente ao servidor. Por predefinição, as ligações HTTP são encerradas após cada solicitação. Para evitar isso, basta passar o cabeçalho `Keep-Alive`.
No que diz respeito aos cabeçalhos HTTP com o Axios, não há realmente nada de especial nisso. Como já discutimos, o Axios é um cliente HTTP e já estabelecemos que os clientes HTTP podem enviar e receber cabeçalhos.
Por que o Axios é um excelente cliente HTTP para JavaScript
Agora que já temos uma visão geral do funcionamento do HTTP, vamos falar dos «clientes». O JavaScript oferece algumas opções para «interagir programaticamente» com um servidor através do HTTP. Entre as opções mais populares, destacam-se o `axios`, o `node-fetch` e o `got`.
Na comunidade JavaScript, há opiniões divergentes sobre qual utilizar. É claro que cada pacote tem os seus prós e contras; no entanto, eu próprio optei pelo Axios após realizar um teste de velocidade simples entre os três.
Aqui está o script que utilizei para testar a velocidade:
// index.js
import { get_timing, array_sum } from './helpers.js'
import got from 'got'
import axios from 'axios'
const CALLS = 5
const send = async () => {
const res = {}
let start = process.hrtime()
await got('https://httpbin.org/')
const g = get_timing(start)
res.got = g
start = process.hrtime()
await axios.get('https://httpbin.org/')
const a = get_timing(start)
res.axios = a
start = process.hrtime()
await fetch('https://httpbin.org/')
const f = get_timing(start)
res.fetch = f
return res
}
let test_results = {
got: [],
axios: [],
fetch: []
}
let avg = {}
console.log(`[i] Process started with ${CALLS} iterations.`)
for (let i = 0; i<=CALLS; i++) {
let r = await send()
Object.entries(test_results).map(([key, value]) => test_results[key].push(r[key]))
}
Object.entries(test_results).forEach(([key, value]) => {
console.log(`\n[+] ${key}`)
console.log(` [i] Average: ${array_sum(value)/value.length}`)
console.log(` [i] Values: ${value}`)
avg[key] = array_sum(value)/value.length
}
)
console.log(`\n🚀🚀🚀 WINNER: ${Object.keys(avg).reduce((key, v) => avg[v] < avg[key] ? v : key)} [${CALLS} calls sent] 🚀🚀🚀`)
E aqui estão as funções «auxiliares»:
// helpers.js
export const get_timing = (start) => {
const NS_PER_SEC = 1e9
const NS_TO_MS = 1e6
const diff = process.hrtime(start)
return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS
}
export const array_sum = (array) => {
return array.reduce((accumulator, value) => {
return accumulator + value
}, 0)
}
Testei com 5, 10, 20 e 30 pedidos enviados por cada pacote, com 10 iterações em cada caso, e eis um resumo dos resultados:

Por «iteração», refiro-me ao número de execuções do script, utilizando esta fórmula do Bash, que gera um ficheiro .txt com os resultados de cada iteração:
~ » for i in {1..10}
do
node got.js > "${i}.txt"
echo "${i} concluído"
done
Como poderá verificar na tabela de resultados detalhados, os tempos variam de lote para lote e, por vezes, o Axios não é o mais rápido. No geral, porém, o Axios registou uma média de 387 milissegundos, sendo meio segundo mais rápido do que os seus concorrentes. O Got e o Fetch tiveram um tempo de resposta muito semelhante, com uma média de aproximadamente 435 milissegundos. Dito isto, se a velocidade é importante para o seu projeto, o Axios é talvez o melhor cliente HTTP para si.
Como enviar cabeçalhos HTTP com o Axios
Pessoalmente, acho que aprender na prática traz resultados quase imediatos. Assim, agora que temos tanto o conhecimento como as ferramentas para enviar cabeçalhos HTTP, vamos começar a trabalhar num pequeno projeto. Nesta secção, vamos criar um novo projeto Node, instalar o Axios e utilizá-lo para enviar cabeçalhos HTTP a um servidor.
Configurar o projeto
Antes de prosseguir, certifique-se de que a sua máquina está equipada com:
- Node.js – pode descarregá-lo aqui
- Um IDE – o IDE que utilizo no dia-a-dia é o Visual Studio Code
Dica: Pode verificar se tem o Node.js instalado digitando o seguinte comando no seu terminal:
~ » node -v
v19.3.0
Agora vamos criar uma nova pasta e abri-la no nosso IDE. Se estiver a utilizar um sistema semelhante ao UNIX (Mac ou Linux), pode criar um novo diretório programaticamente, a partir do terminal, digitando o seguinte comando:
~ » mkdir axios_project && cd axios_project
~ » npm init -y
~ » npm i axios
~ » touch index.js
~ » code .
Estes comandos irão:
- Crie um novo diretório (chamado «axios_project») e aceda a ele
- Inicializar um novo projeto Node.js dentro do diretório
- Instale o `axios` no seu projeto
- Crie um novo ficheiro «index.js»
- Abra o seu IDE no projeto atual
Código para aprender
Na verdade, existem várias formas de enviar cabeçalhos HTTP com o Axios. Por exemplo, pode utilizar um objeto de configuração, tal como descrito aqui, ou pode recorrer aos métodos de instância, que irão combinar automaticamente a configuração que passar com a configuração da instância. Também pode utilizar o objeto `axios.defaults.headers.common` para definir cabeçalhos predefinidos para todas as solicitações do Axios.
Além disso, note que o Axios é um cliente HTTP baseado em promessas. Isto significa que teremos de aguardar a resposta dentro de uma função assíncrona ou resolver a resposta.
Tendo estes dois aspetos em mente, vamos começar a programar. Vamos trabalhar no ficheiro «index.js». Por uma questão de conveniência, vamos recapitular o que precisamos de fazer antes:
- Importar o `axios` para o nosso ficheiro
- Defina um objeto de configuração que irá conter os nossos cabeçalhos
- Passe a configuração para o `axios` para efetuar uma solicitação
- Imprimir a resposta no nosso terminal
N.º 1: Enviar um pedido GET utilizando o objeto de configuração
import axios from "axios"
const config = {
method: 'GET',
url: 'https://httpbin.org/headers',
headers: {
'HTTP-Axios-Headers': 'This is my custom header.'
}
}
axios(config)
.then((response) => {
console.log(response)
})
.catch((err) => {
console.log(err)
})
Enviar cabeçalhos HTTP com o Axios é extremamente simples. Para executar este script, basta executar o seguinte comando no terminal:
~ » node index.js
{
status: 200,
statusText: 'OK',
headers: ...,
config: ...,
request: ...,
data: {
headers: {
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, compress, deflate, br',
'Host': 'httpbin.org',
'Http-Axios-Headers': 'This is my custom header.',
'User-Agent': 'axios/1.2.2',
'X-Amzn-Trace-Id': 'Root=1-63b54d94-7656f02113483dfa036c476c'
}
}
}
A resposta completa é bastante extensa e segue este esquema. No entanto, o que mais nos interessa é o `data`, que contém a resposta efetiva que recebemos do servidor. Agora, observe a resposta acima. Lembre-se de que enviámos um cabeçalho personalizado `Http-Axios-Headers` ao servidor e, como pode ver, o servidor recebeu-o.
N.º 2: Enviar um pedido POST utilizando o alias do método
import axios from "axios"
const data = {
'foo':'bar'
}
const config = {
headers: {
'HTTP-Axios-Headers': 'This is my custom header.'
}
}
axios.post('http://httpbin.org/post', data, config)
.then(response => console.log(response.data))
.catch(err => console.log(err))
Repare que, para enviar um pedido POST, adicionei um novo objeto `data` ao nosso script e também alterei o URL. Agora, se executar o script, verá que estes são os dados recebidos do servidor:
{
args: {},
data: '{"foo":"bar"}',
files: {},
form: {},
headers: {
Accept: 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, compress, deflate, br',
'Content-Length': '13',
'Content-Type': 'application/json',
Host: 'httpbin.org',
'Http-Axios-Headers': 'This is my custom header.',
'User-Agent': 'axios/1.2.2',
'X-Amzn-Trace-Id': 'Root=1-63b5508a-3a86493f087662d3169e80ee'
},
json: { foo: 'bar' },
origin: '49.12.221.20',
url: 'http://httpbin.org/post'
}Como utilizar cabeçalhos HTTP no Axios para a extração de dados da Web
Se tenciona utilizar o Axios para a extração de dados da Web, tenha em atenção que a maioria dos sites possui regras de proteção que bloqueiam os pedidos provenientes de software automatizado (incluindo programas de extração de dados).
A utilização de cabeçalhos HTTP, em particular o cabeçalho `User-Agent`, pode ser uma técnica útil para evitar a deteção durante a extração de dados da Web. O cabeçalho User-Agent identifica o navegador do cliente e o sistema operativo junto do servidor, e os servidores Web podem apresentar conteúdos diferentes ou bloquear pedidos com base nessas informações. Ao definir o cabeçalho User-Agent, é possível simular um navegador Web comum, aumentando assim as hipóteses de contornar alguns mecanismos de deteção.
Eis um exemplo de como utilizar o cabeçalho User-Agent com o Axios para evitar ser detetado ao fazer web scraping:
import axios from "axios"
axios.defaults.headers.common['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
axios({
method: 'GET',
url: 'https://httpbin.org/get',
}).then(response => {
console.log(response.data)
});
Repare que, desta vez, utilizei a opção «config defaults» do Axios, que aplica o cabeçalho a todas as solicitações futuras. Neste exemplo, o cabeçalho User-Agent está definido para imitar o navegador Chrome num sistema operativo Windows 10. Pode experimentar utilizar diferentes valores de User-Agent ou uma variedade de cabeçalhos diferentes para ver o que funciona melhor para o seu caso de utilização específico.
Vale a pena referir que, embora alterar o cabeçalho User-Agent possa ajudar a evitar a deteção em alguns casos, não se trata de um método infalível, e os servidores web podem continuar a identificar que está a utilizar um scraper. Por isso, é aconselhável utilizar uma combinação de técnicas para evitar a deteção e respeitar os termos de serviço do site.
Conclusões
A utilização de cabeçalhos HTTP com o Axios (ou com qualquer outro cliente HTTP, aliás) pode aumentar a eficiência da comunicação entre um servidor e um cliente. Além disso, pode até ajudar a evitar a deteção quando se está a criar um scraper web. Na verdade, na WebScrapingAPI, utilizamos vários agentes de utilizador como uma das técnicas básicas de evasão.
É claro que a deteção não se limita aos agentes de utilizador, mas é um bom ponto de partida. Aqui está um bom tutorial sobre como evitar que o seu endereço IP seja bloqueado ao fazer web scraping, que o ajudará a compreender melhor como funcionam as técnicas de evasão.
A propósito, sabia que a API de Web Scraping permite definir cabeçalhos personalizados nas suas solicitações? Se não, saiba mais aqui.




