As APIs da Web formam um conjunto de interfaces que permitem que páginas e aplicações no navegador acessem recursos do dispositivo e do próprio ambiente do browser. Em vez de depender apenas de HTML e CSS, essas APIs liberam capacidades como armazenamento local, áudio avançado, comunicação em tempo real, leitura de sensores e integração com recursos do sistema.
O tema também inclui limites importantes: alguns recursos exigem permissões, outros dependem do navegador e do sistema operacional, e há casos em que a Web não alcança o mesmo acesso de um aplicativo nativo. Com uma visão organizada, fica mais claro quando usar cada API e como escrever um código seguro e previsível.
RFID, NFC e a diferença entre hardware dedicado e API Web
RFID (Identificação por Radiofrequência) é uma tecnologia em que etiquetas (tags) se comunicam por rádio com leitores para identificar objetos. Em celulares, o parente mais próximo é o NFC (Near Field Communication), que opera a curta distância e é comum em pagamentos por aproximação e leitura de tags. No mundo Web, o acesso direto a RFID “genérico” não é um padrão amplo, porque leitores podem exigir drivers e permissões fora do alcance do navegador. Por isso, RFID costuma ser feito por hardware específico e software nativo (Android e iOS) ou por leitores USB com integração via desktop.
Quando um leitor RFID se apresenta ao sistema como dispositivo USB, o navegador normalmente não “enxerga” esse leitor automaticamente como uma fonte de tags. Em alguns cenários, a leitura vira “entrada de teclado” (HID), onde o leitor “digita” um código em um campo de texto, o que funciona sem API especial, mas com menos controle. Em aplicações mais robustas, entram integrações nativas (apps) ou aplicações desktop que conversam com o leitor e repassam dados para a Web. Já o NFC tem uma API Web em alguns ambientes, permitindo leitura e escrita de mensagens NDEF (NFC Data Exchange Format).
Web NFC API para leitura de tags NFC
A Web NFC API é uma interface que permite ler e, em alguns casos, escrever em tags NFC usando o navegador. O objeto central é o NDEFReader, que inicia uma varredura e dispara eventos quando uma tag é aproximada. Por envolver aproximação e dados do mundo físico, normalmente exige contexto seguro (HTTPS) e permissões do usuário. A disponibilidade varia bastante entre navegadores e sistemas, então é comum ter lógica de detecção e caminhos alternativos.
O exemplo a seguir mostra uma leitura básica de mensagens NDEF, registrando no console os dados recebidos. Ele ilustra o fluxo típico: instanciar o leitor, iniciar o scan e reagir ao evento de leitura. Em implementações reais, costuma existir tratamento de erros, cancelamento e extração detalhada de registros (records) dentro da mensagem. Também é comum registrar no estado da aplicação quando o scan está ativo para evitar chamadas duplicadas.
// Leitura básica de NFC com Web NFC (experimental)
async function iniciarLeituraNFC() {
if (!("NDEFReader" in window)) {
console.error("Web NFC indisponível neste navegador/ambiente.");
return;
}
try {
const leitor = new NDEFReader();
await leitor.scan();
leitor.onreading = (evento) => {
console.log("Mensagem NDEF recebida:", evento.message);
// Exemplo: iterar pelos registros NDEF
for (const registro of evento.message.records) {
console.log("Registro:", {
tipo: registro.recordType,
midia: registro.mediaType,
id: registro.id
});
}
};
leitor.onreadingerror = () => {
console.error("Falha ao ler a tag NFC. Aproximação ou tag incompatível.");
};
} catch (erro) {
console.error("Erro ao iniciar scan NFC:", erro);
}
}
iniciarLeituraNFC();
Payment Request API para fluxo de pagamento padronizado
A Payment Request API oferece uma forma padronizada de apresentar opções de pagamento, sem que o site precise construir toda a experiência de checkout do zero. Ela não cria um “novo método” de pagamento; ela organiza como o navegador coleta e devolve dados de pagamento já existentes. Isso pode reduzir atrito, pois o navegador pode reutilizar informações salvas, como cartões e endereços, quando suportado. Por segurança e consistência, o navegador controla a interface visual do prompt de pagamento.
O fluxo é: declarar métodos suportados, declarar detalhes (como total) e chamar request.show(). Ao final, o código recebe um paymentResponse e confirma a finalização com complete(). Em produção, a validação e a cobrança real acontecem no servidor, e o retorno do servidor determina se a finalização será “success” ou “fail”. O exemplo abaixo mantém o foco na estrutura e no ciclo de vida da API.
// Exemplo básico de Payment Request API
async function solicitarPagamento() {
if (!("PaymentRequest" in window)) {
console.error("Payment Request API não suportada neste navegador.");
return;
}
const instrumentosSuportados = [
{ supportedMethods: "basic-card" }
];
const detalhesPagamento = {
total: {
label: "Total",
amount: { currency: "USD", value: "10.00" }
}
};
try {
const requisicao = new PaymentRequest(instrumentosSuportados, detalhesPagamento);
const resposta = await requisicao.show();
// Em um cenário real, aqui ocorreria a validação no servidor e a cobrança.
await resposta.complete("success");
console.log("Pagamento concluído com sucesso.");
} catch (erro) {
console.error("Pagamento cancelado ou falhou:", erro);
}
}
solicitarPagamento();
Push API para mensagens enviadas do servidor ao navegador
A Push API permite que uma aplicação Web receba mensagens “empurradas” por um servidor, mesmo quando a página não está em primeiro plano. Na prática, ela costuma ser usada junto com Service Worker, que é um script em segundo plano capaz de reagir a eventos de push e exibir notificações. O navegador gerencia uma inscrição (subscription) por meio do PushManager, e o servidor envia mensagens para um endpoint associado a essa inscrição. Como envolve interrupções e permissão, o usuário precisa autorizar notificações.
O trecho a seguir mostra a checagem de suporte e a solicitação de permissão de notificação. Para um fluxo completo, seria necessário registrar um Service Worker, obter a inscrição via pushManager.subscribe() e enviar a subscription ao servidor. Também é comum lidar com revogação de permissão e com revalidação periódica da inscrição. O exemplo mantém o foco nos pontos mínimos para iniciar corretamente.
// Checagem básica de suporte e permissão para Push/Notificações
function configurarPushBasico() {
if (!("PushManager" in window)) {
console.error("Push API não suportada neste navegador.");
return;
}
if (!("Notification" in window)) {
console.error("Notifications API não suportada neste navegador.");
return;
}
Notification.requestPermission().then((permissao) => {
if (permissao === "granted") {
console.log("Permissão concedida. Assinatura (subscription) viria aqui.");
} else {
console.log("Permissão negada ou padrão.");
}
});
}
configurarPushBasico();
Web Speech API: síntese de fala e reconhecimento de voz
A Web Speech API reúne recursos relacionados a voz, incluindo síntese de fala (texto para voz) e, em alguns navegadores, reconhecimento de fala (voz para texto). A síntese costuma ser exposta via SpeechSynthesis e SpeechSynthesisUtterance, permitindo configurar idioma, velocidade e volume. Já o reconhecimento pode variar por navegador e frequentemente aparece com prefixos, como webkitSpeechRecognition. Por envolver microfone e processamento de áudio, permissões e compatibilidade são pontos centrais.
O exemplo abaixo é de síntese de fala, em que uma frase é transformada em áudio pelo mecanismo do navegador. Em aplicações reais, é comum controlar fila de falas e cancelar falas em andamento com speechSynthesis.cancel(). Também pode ser útil selecionar vozes disponíveis via speechSynthesis.getVoices(), pois nem sempre há a mesma disponibilidade de vozes por sistema. O trecho abaixo mantém o comportamento simples e direto.
// Texto para fala com Web Speech API (síntese)
function falarTexto() {
const textoParaFalar = "Olá, esta é uma demonstração de síntese de fala.";
const fala = new SpeechSynthesisUtterance(textoParaFalar);
fala.lang = "pt-BR";
fala.rate = 1.0;
fala.pitch = 1.0;
fala.volume = 1.0;
window.speechSynthesis.speak(fala);
}
falarTexto();
Speech Recognition (voz para texto) com compatibilidade limitada
O reconhecimento de fala converte áudio do microfone em texto, possibilitando ditado e comandos por voz. Em vários ambientes, a API é exposta como webkitSpeechRecognition, o que indica suporte não padronizado em todos os navegadores. Normalmente é necessário lidar com eventos como resultado, erro e fim da captura. Também é importante considerar que o reconhecimento pode depender de serviços do navegador e variar em qualidade conforme ruído e idioma.
O exemplo a seguir inicia uma sessão simples e registra a transcrição do primeiro resultado. Em um cenário mais completo, seria comum habilitar resultados contínuos, tratar resultados parciais e controlar reinícios quando a captura termina. Também é relevante tratar o caso em que o suporte não existe e oferecer alternativas. O código foca no mínimo para demonstrar o fluxo de eventos.
// Voz para texto (suporte comum em Chrome/Edge via prefixo)
function iniciarReconhecimentoDeVoz() {
const Reconhecimento = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!Reconhecimento) {
console.error("Reconhecimento de fala indisponível neste navegador.");
return;
}
const reconhecimento = new Reconhecimento();
reconhecimento.lang = "pt-BR";
reconhecimento.interimResults = false;
reconhecimento.continuous = false;
reconhecimento.onresult = (e) => {
const texto = e.results[0][0].transcript;
console.log("Texto reconhecido:", texto);
};
reconhecimento.onerror = (e) => {
console.error("Erro no reconhecimento de voz:", e.error);
};
reconhecimento.onend = () => {
console.log("Reconhecimento finalizado.");
};
reconhecimento.start();
}
iniciarReconhecimentoDeVoz();
Fetch API para requisições HTTP modernas
A Fetch API é a interface moderna para buscar recursos pela rede usando HTTP. Ela trabalha com Promises, que representam operações assíncronas, e retorna um objeto Response com status, cabeçalhos e corpo. Em JSON, é comum chamar response.json() para converter o corpo para objeto JavaScript. Para qualidade de código, é importante verificar response.ok e tratar erros de rede e erros HTTP de forma separada.
O exemplo abaixo busca um JSON, valida se a resposta foi bem-sucedida e então imprime os dados. Em produção, também entram controle de timeout (por exemplo via AbortController), envio de cabeçalhos e autenticação. Outro cuidado relevante é o CORS (Cross-Origin Resource Sharing), que controla se um servidor permite requisições vindas de outra origem. O trecho abaixo cobre o padrão mais comum e seguro para iniciantes.
// Requisição HTTP com Fetch API e validação de status
async function carregarFilmes() {
try {
const resposta = await fetch("http://example.com/movies.json", {
method: "GET",
headers: { "Accept": "application/json" }
});
if (!resposta.ok) {
throw new Error("Resposta HTTP inválida: " + resposta.status);
}
const dados = await resposta.json();
console.log("Dados recebidos:", dados);
} catch (erro) {
console.error("Erro na requisição:", erro);
}
}
carregarFilmes();
Web Audio API para geração e processamento de áudio
A Web Audio API fornece um sistema avançado para criar e manipular áudio no navegador. Ela funciona com um grafo de nós, em que fontes (como osciladores e arquivos) passam por efeitos e chegam até a saída de áudio. O ponto de entrada é um AudioContext, que controla tempo, criação de nós e roteamento. Por políticas de reprodução automática, muitos navegadores exigem que o áudio comece após uma interação do usuário.
O exemplo a seguir cria um oscilador com frequência de 440 Hz, o “Lá” padrão, e toca por um segundo. Em aplicações mais elaboradas, entram nós como GainNode (volume), BiquadFilterNode (filtros) e analisadores para visualização. Também é comum gerenciar o ciclo de vida do contexto e liberar recursos. O exemplo mantém a estrutura essencial para demonstrar criação, conexão e execução.
// Geração simples de tom com Web Audio API
async function tocarTom() {
const AudioCtx = window.AudioContext || window.webkitAudioContext;
if (!AudioCtx) {
console.error("Web Audio API não suportada neste navegador.");
return;
}
const contexto = new AudioCtx();
const oscilador = contexto.createOscillator();
oscilador.type = "sine";
oscilador.frequency.setValueAtTime(440, contexto.currentTime);
const ganho = contexto.createGain();
ganho.gain.setValueAtTime(0.1, contexto.currentTime); // volume baixo
oscilador.connect(ganho);
ganho.connect(contexto.destination);
oscilador.start();
oscilador.stop(contexto.currentTime + 1);
oscilador.onended = async () => {
await contexto.close();
};
}
tocarTom();
File API para acesso a arquivos selecionados pelo usuário
A File API permite que a aplicação leia metadados e conteúdo de arquivos fornecidos pelo próprio usuário, geralmente via um elemento input do tipo file. O navegador não permite acesso arbitrário ao disco; o usuário precisa escolher o arquivo. Uma vez selecionado, o arquivo aparece como um objeto File, que é um tipo de Blob (dados binários). A leitura do conteúdo pode ser feita por FileReader ou por métodos modernos como file.text().
O exemplo abaixo mostra a captura do arquivo selecionado e a leitura como texto quando aplicável. Em uploads reais, o arquivo é enviado com fetch usando FormData para multipart/form-data. Também é importante validar tamanho, tipo MIME e lidar com múltiplos arquivos. O trecho abaixo mantém o foco no acesso inicial e na inspeção do arquivo.
O bloco a seguir apresenta um exemplo completo em HTML e JavaScript para selecionar um arquivo e ler seu conteúdo.
<input type="file" id="entradaArquivo" accept="image/*,text/plain">
<button id="btnLer">Ler arquivo</button>
<script>
async function lerArquivoSelecionado() {
const input = document.getElementById("entradaArquivo");
const arquivo = input.files && input.files[0];
if (!arquivo) {
console.log("Nenhum arquivo selecionado.");
return;
}
console.log("Arquivo:", {
nome: arquivo.name,
tipo: arquivo.type,
tamanho: arquivo.size
});
if (arquivo.type.startsWith("text/")) {
const conteudo = await arquivo.text();
console.log("Conteúdo do texto:", conteudo);
} else {
console.log("Arquivo não textual selecionado.");
}
}
document.getElementById("btnLer").addEventListener("click", lerArquivoSelecionado);
</script>
IndexedDB para armazenamento estruturado e volumoso no navegador
IndexedDB é uma API de baixo nível para armazenar grandes volumes de dados estruturados no lado do cliente. Ela é baseada em bancos de dados com object stores (semelhantes a tabelas simples) e indexes (índices) para consultas rápidas. Diferente de armazenamento por chave/valor simples, o IndexedDB suporta buscas eficientes e guarda objetos complexos. Por ser assíncrona e orientada a eventos, a abertura do banco envolve callbacks como onupgradeneeded e onsuccess.
Um ponto crítico é o controle de versão: ao mudar a estrutura do banco, incrementa-se a versão e cria-se ou ajusta-se stores e índices no onupgradeneeded. Também é essencial entender transações, porque leituras e escritas acontecem dentro de uma transaction. O exemplo abaixo cria um banco simples com uma store de posts e demonstra inserção e leitura. Ele serve como base para cache offline, rascunhos e dados de sessão persistentes.
O bloco a seguir apresenta a abertura do banco, criação de store e operações básicas.
// IndexedDB: criação de banco, store e operações básicas
const nomeBanco = "PostsDB";
const versaoBanco = 1;
function abrirBanco() {
return new Promise((resolve, reject) => {
const requisicao = indexedDB.open(nomeBanco, versaoBanco);
requisicao.onerror = () => reject(new Error("Erro ao abrir o banco IndexedDB."));
requisicao.onupgradeneeded = (evento) => {
const db = evento.target.result;
if (!db.objectStoreNames.contains("posts")) {
const store = db.createObjectStore("posts", { keyPath: "id" });
store.createIndex("porData", "criadoEm", { unique: false });
}
};
requisicao.onsuccess = () => resolve(requisicao.result);
});
}
async function salvarPost(post) {
const db = await abrirBanco();
return new Promise((resolve, reject) => {
const tx = db.transaction("posts", "readwrite");
const store = tx.objectStore("posts");
const req = store.put(post);
req.onsuccess = () => resolve(true);
req.onerror = () => reject(new Error("Falha ao salvar post."));
tx.oncomplete = () => db.close();
});
}
async function listarPosts() {
const db = await abrirBanco();
return new Promise((resolve, reject) => {
const tx = db.transaction("posts", "readonly");
const store = tx.objectStore("posts");
const req = store.getAll();
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(new Error("Falha ao listar posts."));
tx.oncomplete = () => db.close();
});
}
// Demonstração
(async () => {
await salvarPost({ id: "1", texto: "Primeiro post", criadoEm: Date.now() });
const posts = await listarPosts();
console.log("Posts:", posts);
})();
WebSockets para comunicação bidirecional em tempo real
A WebSocket API permite abrir uma conexão persistente e bidirecional entre navegador e servidor. Diferente de requisições HTTP tradicionais, que são pontuais, o WebSocket mantém um canal aberto para envio e recebimento imediato de mensagens. Isso é útil para chat, atualizações em tempo real, telemetria e dashboards ao vivo. O endereço começa com wss:// quando a conexão é criptografada.
O exemplo abaixo cria um socket, envia uma mensagem ao abrir e registra mensagens recebidas. Em cenários reais, entram estratégias de reconexão, autenticação e protocolos de mensagens (por exemplo JSON com tipo e payload). Também é comum tratar eventos de erro e encerrar a conexão adequadamente. O trecho demonstra o ciclo básico de eventos: open, message e close.
// Comunicação em tempo real com WebSocket
function iniciarWebSocket() {
const socket = new WebSocket("wss://example.com/socket");
socket.addEventListener("open", () => {
console.log("Conexão aberta.");
socket.send("Olá, servidor!");
});
socket.addEventListener("message", (event) => {
console.log("Mensagem recebida:", event.data);
});
socket.addEventListener("error", () => {
console.error("Erro no WebSocket.");
});
socket.addEventListener("close", () => {
console.log("Conexão encerrada.");
});
return socket;
}
iniciarWebSocket();
Notifications API para notificações do sistema
A Notifications API permite exibir notificações do sistema operacional a partir do navegador, desde que haja permissão. Ela é frequentemente combinada com Push e Service Workers, mas também pode ser usada localmente enquanto a página está aberta. Como envolve interrupção, a permissão pode ser “granted”, “denied” ou “default”. Em alguns navegadores, o conteúdo e o comportamento podem variar para manter consistência e segurança.
O exemplo a seguir solicita permissão e cria uma notificação simples. Em usos mais completos, pode-se usar opções como body, icon e ações, além de tratar cliques na notificação. Também é importante evitar excessos para não degradar a experiência e causar bloqueios de permissão. O trecho demonstra o fluxo mínimo com tratamento básico do resultado.
// Notificação simples com Notifications API
async function notificar() {
if (!("Notification" in window)) {
console.error("Notifications API não suportada neste navegador.");
return;
}
const permissao = await Notification.requestPermission();
if (permissao === "granted") {
new Notification("Olá, mundo!", { body: "Notificação exibida pelo navegador." });
} else {
console.log("Permissão não concedida:", permissao);
}
}
notificar();
Intersection Observer para observar elementos entrando na tela
A Intersection Observer API observa mudanças de interseção entre um elemento alvo e o viewport, sem precisar de cálculos constantes de scroll. Isso é útil para carregamento preguiçoso (lazy loading), animações ao aparecer e métricas de visibilidade. Ela funciona de forma assíncrona e tende a ser mais eficiente do que escutar scroll e recalcular posições. O observador recebe entradas (entries) com informações como isIntersecting e proporção visível.
O exemplo abaixo observa um elemento e registra quando ele entra no viewport. Em casos reais, configura-se threshold e rootMargin para ajustar a sensibilidade e antecipar carregamento. Também é comum chamar unobserve após a primeira interseção, para não repetir processamento. O código mostra a estrutura essencial e o ponto de observação.
// Observação de visibilidade com IntersectionObserver
function observarElemento(idElemento) {
const alvo = document.getElementById(idElemento);
if (!alvo) {
console.error("Elemento não encontrado:", idElemento);
return;
}
const observer = new IntersectionObserver((entradas) => {
entradas.forEach((entrada) => {
if (entrada.isIntersecting) {
console.log("Elemento visível no viewport:", idElemento);
}
});
}, { threshold: 0.1 });
observer.observe(alvo);
}
observarElemento("yourElementId");
Web Workers para executar tarefas em segundo plano
Web Workers permitem rodar JavaScript em uma thread separada da thread principal da página. Isso ajuda a evitar travamentos na interface quando há cálculos pesados, como processamento de dados, compressão ou parsing grande. A comunicação acontece por mensagens com postMessage e eventos de message. O Worker não acessa diretamente o DOM, o que reforça separação e previsibilidade.
O exemplo abaixo mostra a criação de um worker e a troca de mensagens. Em cenários reais, pode-se enviar objetos grandes usando cópia estruturada e, quando possível, usar Transferable para mover buffers sem copiar. Também é importante lidar com erros do worker e encerrá-lo com terminate() quando não for mais necessário. O trecho inclui o script principal e um exemplo de arquivo worker.
O bloco a seguir apresenta o código do script principal.
// Script principal: cria worker e envia mensagem
function iniciarWorker() {
const worker = new Worker("worker.js");
worker.onmessage = (e) => {
console.log("Mensagem do worker:", e.data);
};
worker.onerror = () => {
console.error("Erro no worker.");
};
worker.postMessage({ texto: "Olá do script principal!", numero: 10 });
return worker;
}
iniciarWorker();
O bloco a seguir apresenta um exemplo de conteúdo para o arquivo worker.js.
// worker.js: processa dados em segundo plano
self.onmessage = (e) => {
const { texto, numero } = e.data;
// Processamento simples para demonstração
const resultado = {
recebido: texto,
dobro: numero * 2
};
self.postMessage(resultado);
};
Mutation Observer para detectar alterações no DOM
A MutationObserver API monitora mudanças na árvore DOM, como adição/remoção de nós e alterações de atributos. Ela substitui eventos antigos de mutação, oferecendo melhor desempenho e um modelo de observação mais controlado. Isso é útil para componentes que precisam reagir quando um trecho da página muda, como listas dinâmicas ou integração com conteúdo inserido por terceiros. O observador recebe uma lista de mutações, cada uma descrevendo o que mudou.
O exemplo abaixo observa atributos, filhos e subárvore de um elemento. Em produção, é comum filtrar tipos de mutação e desligar a observação quando não for necessária, evitando processamento constante. Também é importante evitar loops, onde o código reage a uma mutação gerando outra mutação repetidamente. O trecho mostra a configuração essencial e o início da observação.
// Detecção de mudanças no DOM com MutationObserver
function observarMudancasDOM(idElemento) {
const alvo = document.getElementById(idElemento);
if (!alvo) {
console.error("Elemento não encontrado:", idElemento);
return;
}
const observer = new MutationObserver((mutacoes) => {
mutacoes.forEach((mutacao) => {
console.log("Mudança detectada:", {
tipo: mutacao.type,
atributo: mutacao.attributeName
});
});
});
const config = { attributes: true, childList: true, subtree: true };
observer.observe(alvo, config);
return observer;
}
observarMudancasDOM("yourElementId");
Pointer Lock API para capturar movimento bruto do mouse
A Pointer Lock API permite “travar” o ponteiro do mouse em um elemento e receber movimento relativo, em vez da posição absoluta do cursor. Isso é muito usado em jogos 3D e experiências imersivas, onde o movimento contínuo do mouse controla câmera e rotação. Por segurança e previsibilidade, a ativação geralmente precisa ocorrer após uma interação do usuário. O estado pode ser acompanhado por eventos como pointerlockchange.
O exemplo abaixo solicita o pointer lock em um elemento. Em um cenário completo, é comum também ouvir movimento do mouse com mousemove e usar as propriedades movementX e movementY. Também é importante oferecer uma forma clara de sair do lock, geralmente via tecla Esc, gerenciada pelo próprio navegador. O trecho apresenta a chamada central e um monitoramento simples de mudança de estado.
// Ativação de Pointer Lock em um elemento
function ativarPointerLock(idElemento) {
const elemento = document.getElementById(idElemento);
if (!elemento) {
console.error("Elemento não encontrado:", idElemento);
return;
}
document.addEventListener("pointerlockchange", () => {
const travado = document.pointerLockElement === elemento;
console.log("Pointer lock ativo:", travado);
});
elemento.requestPointerLock();
}
ativarPointerLock("yourElementId");
Web Storage API: sessionStorage e localStorage
A Web Storage API oferece armazenamento simples de pares chave/valor em formato de string. O sessionStorage dura enquanto a aba estiver aberta, e é isolado por aba. O localStorage persiste mesmo após fechar e abrir o navegador, dentro do mesmo domínio. Por serem strings, objetos precisam ser serializados, normalmente com JSON.stringify, e recuperados com JSON.parse.
O exemplo abaixo mostra gravação, leitura e remoção em ambos. O Web Storage é útil para preferências simples e pequenos estados, mas não é ideal para grandes volumes ou buscas complexas, onde o IndexedDB é mais apropriado. Também é importante evitar guardar dados sensíveis, pois ficam acessíveis por scripts do mesmo domínio. O trecho demonstra os dois tipos e um padrão seguro para objetos com JSON.
// sessionStorage: dura enquanto a aba existir
sessionStorage.setItem("chave", "valor");
const valorSession = sessionStorage.getItem("chave");
console.log("sessionStorage:", valorSession);
sessionStorage.removeItem("chave");
// localStorage: persiste no navegador
localStorage.setItem("chave", "valor");
const valorLocal = localStorage.getItem("chave");
console.log("localStorage:", valorLocal);
localStorage.removeItem("chave");
// Salvando objeto com JSON
const preferencias = { tema: "escuro", tamanhoFonte: 16 };
localStorage.setItem("preferencias", JSON.stringify(preferencias));
const preferenciasLidas = JSON.parse(localStorage.getItem("preferencias") || "{}");
console.log("Preferências:", preferenciasLidas);
Battery Status API para obter informações de bateria
A Battery Status API (ou Battery API) fornece informações como nível de carga e se o dispositivo está carregando. Ela pode ajudar a adaptar comportamentos, como reduzir tarefas pesadas quando a bateria está baixa. A API retorna um objeto de bateria com propriedades e eventos, permitindo reagir a mudanças. Por questões de privacidade e padronização, a disponibilidade pode ser limitada em alguns navegadores.
O exemplo abaixo lê nível e estado de carregamento. Em usos mais avançados, pode-se assinar eventos como levelchange e chargingchange. Também é relevante tratar o caso de não suporte, evitando falhas silenciosas. O trecho demonstra leitura inicial com logs simples.
// Informações de bateria com Battery API (quando disponível)
async function lerBateria() {
if (!navigator.getBattery) {
console.error("Battery API não suportada neste navegador.");
return;
}
const bateria = await navigator.getBattery();
console.log("Nível da bateria:", Math.round(bateria.level * 100) + "%");
console.log("Carregando:", bateria.charging ? "Sim" : "Não");
}
lerBateria();
Orientation and Motion API para sensores de orientação e movimento
A Orientation and Motion API usa sensores do dispositivo, como acelerômetro e giroscópio, para expor orientação e movimento. O evento deviceorientation fornece ângulos que representam rotação do aparelho em diferentes eixos. O evento devicemotion fornece aceleração e, em alguns casos, rotação. Por privacidade e segurança, alguns ambientes exigem permissões explícitas e interação prévia para liberar sensores.
O exemplo abaixo registra eventos e imprime valores básicos. Em aplicações reais, é comum filtrar ruído com suavização, limitar taxa de atualização e lidar com valores nulos dependendo do hardware. Também é útil normalizar comportamento entre dispositivos, pois a calibração pode variar. O trecho demonstra como assinar os dois eventos mais comuns.
// Eventos de orientação e movimento
window.addEventListener("deviceorientation", (event) => {
console.log("Orientação:", {
alpha: event.alpha,
beta: event.beta,
gamma: event.gamma
});
});
window.addEventListener("devicemotion", (event) => {
const acc = event.acceleration;
if (!acc) {
console.log("Aceleração indisponível.");
return;
}
console.log("Movimento:", {
x: acc.x,
y: acc.y,
z: acc.z
});
});
Gamepad API para controle de videogame no navegador
A Gamepad API permite detectar e ler entradas de controles conectados ao dispositivo, como gamepads USB ou Bluetooth. Ela expõe botões e eixos (analógicos), permitindo mapear ações como pular, correr e mover câmera. O navegador dispara eventos quando um controle conecta ou desconecta. Para leitura contínua dos estados, costuma-se usar um loop com requestAnimationFrame.
O exemplo abaixo registra conexão e desconexão e mostra como consultar o estado do controle. Em usos reais, também é comum lidar com múltiplos gamepads e com diferenças de mapeamento entre modelos. Um cuidado importante é evitar assumir que o layout de botões é sempre igual, pois pode variar. O trecho demonstra eventos e uma leitura simples periódica.
// Detecção e leitura simples de Gamepad
window.addEventListener("gamepadconnected", (event) => {
console.log("Gamepad conectado:", event.gamepad.id);
});
window.addEventListener("gamepaddisconnected", (event) => {
console.log("Gamepad desconectado:", event.gamepad.id);
});
function lerEstadoGamepad() {
const gamepads = navigator.getGamepads ? navigator.getGamepads() : [];
const gp = gamepads[0];
if (gp) {
console.log("Eixo 0:", gp.axes[0], "Botão 0 pressionado:", gp.buttons[0].pressed);
}
requestAnimationFrame(lerEstadoGamepad);
}
lerEstadoGamepad();
Clipboard API para copiar texto com segurança
A Clipboard API permite copiar e, em alguns casos, ler dados da área de transferência. O uso mais comum é copiar texto, como códigos, links e resultados de ferramentas. Em geral, é exigido contexto seguro (HTTPS) e, com frequência, uma ação do usuário para permitir a operação. O método navigator.clipboard.writeText retorna uma Promise e permite tratamento de sucesso e falha.
O exemplo abaixo copia uma string e registra o resultado. Em aplicações reais, é comum fornecer retorno visual e tratar erros de permissão, especialmente em navegadores que restringem chamadas automáticas. Também pode haver diferenças de comportamento em ambientes móveis. O trecho mantém o foco no fluxo básico com tratamento de erro.
// Copiar texto para a área de transferência
async function copiarTexto() {
if (!navigator.clipboard || !navigator.clipboard.writeText) {
console.error("Clipboard API não suportada neste navegador.");
return;
}
try {
await navigator.clipboard.writeText("Texto copiado com sucesso!");
console.log("Texto copiado.");
} catch (erro) {
console.error("Falha ao copiar texto:", erro);
}
}
copiarTexto();
Geolocation API para obter localização do dispositivo
A Geolocation API retorna coordenadas aproximadas de latitude e longitude, dependendo de GPS, Wi‑Fi e rede. Por ser um dado sensível, exige permissão e normalmente só funciona em contexto seguro (HTTPS). O método getCurrentPosition traz uma leitura pontual, e watchPosition acompanha mudanças ao longo do tempo. É importante lidar com erros, como permissão negada, timeout e indisponibilidade.
O exemplo abaixo busca a posição atual e registra coordenadas. Em aplicações reais, também se usa precisão (accuracy) e timestamp, além de configurar opções como enableHighAccuracy e timeout. Outro cuidado é que a localização pode ser aproximada em desktops, e pode variar conforme permissões do sistema. O trecho inclui callbacks de sucesso e erro para robustez.
// Localização pontual com Geolocation API
function obterLocalizacao() {
if (!navigator.geolocation) {
console.error("Geolocation API não suportada neste navegador.");
return;
}
navigator.geolocation.getCurrentPosition(
(posicao) => {
console.log("Latitude:", posicao.coords.latitude);
console.log("Longitude:", posicao.coords.longitude);
console.log("Precisão (m):", posicao.coords.accuracy);
},
(erro) => {
console.error("Erro de geolocalização:", erro.code, erro.message);
},
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
);
}
obterLocalizacao();
MediaDevices API para acessar câmera e microfone
A MediaDevices API, através de getUserMedia, permite capturar áudio e vídeo do microfone e da câmera. Ela é usada em chamadas, gravações, leitura de QR Code e captura de imagens. O retorno é um MediaStream, que pode ser ligado a um elemento de vídeo ou áudio. Por envolver hardware e privacidade, requer permissão e normalmente HTTPS.
O exemplo abaixo inicia um stream de vídeo e o conecta a um elemento video. Em aplicações reais, costuma-se enumerar dispositivos com enumerateDevices, escolher câmera frontal/traseira no celular e parar faixas com track.stop() ao finalizar. Também é importante tratar erros como NotAllowedError e NotFoundError. O trecho inclui o HTML mínimo necessário e o JavaScript correspondente.
O bloco a seguir apresenta um exemplo completo de captura de câmera.
<video id="preview" autoplay playsinline muted></video>
<script>
async function iniciarCamera() {
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
console.error("MediaDevices API não suportada neste navegador.");
return;
}
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false });
const video = document.getElementById("preview");
video.srcObject = stream;
console.log("Câmera iniciada.");
} catch (erro) {
console.error("Erro ao acessar câmera:", erro.name, erro.message);
}
}
iniciarCamera();
</script>
MediaRecorder API para gravar áudio (e vídeo, quando suportado)
A MediaRecorder API grava um MediaStream e produz blocos (chunks) de mídia, geralmente em formatos como webm/ogg dependendo do navegador. Ela é comum em mensagens de voz e gravações rápidas no browser. O ciclo típico é criar o MediaRecorder, iniciar, coletar dados via ondataavailable e finalizar com stop. Depois, os chunks são combinados em um Blob para reprodução ou upload.
O exemplo abaixo grava áudio por três segundos e gera um Blob ao final. Em produção, é comum exibir tempo de gravação, permitir pausa com pause() e resume(), e verificar suporte com MediaRecorder.isTypeSupported. Também é importante parar as tracks do microfone após terminar para liberar o hardware. O trecho demonstra o fluxo completo de início, coleta e finalização.
// Gravação simples de áudio com MediaRecorder
async function gravarAudioPor3s() {
if (!navigator.mediaDevices || !window.MediaRecorder) {
console.error("MediaRecorder/MediaDevices indisponíveis neste navegador.");
return;
}
let stream;
try {
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const gravador = new MediaRecorder(stream);
const partes = [];
gravador.ondataavailable = (e) => {
if (e.data && e.data.size > 0) partes.push(e.data);
};
gravador.onstop = () => {
const blob = new Blob(partes, { type: gravador.mimeType || "audio/webm" });
console.log("Áudio gravado (Blob):", blob);
// Libera microfone
stream.getTracks().forEach((t) => t.stop());
};
gravador.start();
console.log("Gravação iniciada.");
setTimeout(() => {
gravador.stop();
console.log("Gravação finalizada.");
}, 3000);
} catch (erro) {
console.error("Erro ao gravar áudio:", erro.name, erro.message);
if (stream) stream.getTracks().forEach((t) => t.stop());
}
}
gravarAudioPor3s();
Fullscreen API para modo tela cheia
A Fullscreen API coloca um elemento, ou a página inteira, em modo tela cheia. É comum em players de vídeo, apresentações e painéis de monitoramento. A entrada e saída do modo tela cheia geralmente exigem gesto do usuário por segurança. O estado pode ser verificado com document.fullscreenElement e eventos como fullscreenchange.
O exemplo abaixo solicita tela cheia para o documento. Em cenários mais controlados, solicita-se para um elemento específico, como um container de vídeo. Também é comum tratar falhas com try/catch e oferecer saída chamando document.exitFullscreen(). O trecho demonstra entrada e observação de mudança.
// Tela cheia com Fullscreen API
async function entrarEmTelaCheia() {
try {
await document.documentElement.requestFullscreen();
console.log("Tela cheia ativada.");
} catch (erro) {
console.error("Falha ao ativar tela cheia:", erro);
}
}
document.addEventListener("fullscreenchange", () => {
console.log("Estado fullscreen:", !!document.fullscreenElement);
});
entrarEmTelaCheia();
Drag and Drop API para arrastar e soltar arquivos
A Drag and Drop API permite arrastar itens, incluindo arquivos do sistema, para dentro da página. Em uploads, é comum prevenir o comportamento padrão do navegador e ler dataTransfer.files. A API trabalha com eventos como dragover e drop. Como o input é fornecido pelo usuário, é um fluxo natural para seleção de arquivos.
O exemplo abaixo captura arquivos soltos no documento. Em implementações reais, costuma-se limitar a área de drop a um elemento específico e validar tipos e tamanhos. Também é comum adicionar feedback visual durante dragover e remover ao dragleave. O trecho mostra o essencial para interceptar e obter a lista de arquivos.
// Drag and Drop básico para capturar arquivos
document.addEventListener("dragover", (e) => {
e.preventDefault();
});
document.addEventListener("drop", (e) => {
e.preventDefault();
const arquivos = e.dataTransfer.files;
console.log("Arquivos soltos:", arquivos);
});
Network Information API para estimar tipo de conexão
A Network Information API expõe informações estimadas sobre a conexão, como effectiveType, que pode indicar “slow-2g”, “2g”, “3g” ou “4g”. Isso pode orientar decisões como reduzir qualidade de mídia e adiar downloads pesados. Por ser um dado sensível e variável, o suporte pode ser parcial e os valores são aproximações. Em geral, ela é um sinal para adaptação, não uma garantia de velocidade real.
O exemplo abaixo registra o effectiveType quando disponível. Em um caso completo, também se observa mudanças com evento “change” na conexão. É importante sempre ter fallback, pois a API pode não existir. O trecho demonstra leitura defensiva e log do valor.
// Leitura simples de tipo de conexão (quando suportado)
function lerInfoRede() {
const conexao = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
if (!conexao) {
console.error("Network Information API não suportada neste navegador.");
return;
}
console.log("Tipo efetivo de conexão:", conexao.effectiveType);
}
lerInfoRede();
Page Visibility API para detectar quando a página está oculta
A Page Visibility API informa se a página está visível ou em segundo plano, o que ajuda a reduzir consumo de CPU e bateria. Quando o documento fica oculto, pode-se pausar animações, timers e atualizações desnecessárias. O estado é exposto por document.hidden e pelo evento visibilitychange. É uma API simples, mas muito útil para otimização.
O exemplo abaixo registra mudanças de visibilidade. Em aplicações reais, essa informação pode ser combinada com estado de reprodução de mídia, sincronização e reconexão de sockets. Também é útil para adiar processamento pesado até a aba voltar ao foco. O trecho demonstra o padrão de assinatura do evento.
// Monitoramento de visibilidade da página
document.addEventListener("visibilitychange", () => {
console.log(document.hidden ? "Página oculta" : "Página ativa");
});
File System Access API para salvar arquivo localmente (suporte limitado)
A File System Access API permite abrir e salvar arquivos diretamente no sistema de arquivos, com um seletor controlado pelo navegador. Ela é muito útil em editores online e exportações, porque o conteúdo pode ser gravado sem precisar gerar download tradicional. Por segurança, sempre depende de interação do usuário e do prompt do navegador. O suporte costuma ser mais presente em navegadores baseados em Chromium.
O exemplo abaixo abre o seletor de salvamento, cria um escritor (writable), grava texto e fecha o arquivo. Em usos mais completos, também é comum salvar binários, manter o handle para salvamentos subsequentes e tratar cancelamento do seletor. Também é importante capturar exceções, pois o usuário pode cancelar a operação. O trecho demonstra o ciclo completo de escrita.
// Salvamento local com File System Access API (quando suportado)
async function salvarArquivoLocal() {
if (!window.showSaveFilePicker) {
console.error("File System Access API não suportada neste navegador.");
return;
}
try {
const handle = await window.showSaveFilePicker({
suggestedName: "arquivo.txt",
types: [
{
description: "Texto",
accept: { "text/plain": [".txt"] }
}
]
});
const writable = await handle.createWritable();
await writable.write("Conteúdo do arquivo");
await writable.close();
console.log("Arquivo salvo com sucesso.");
} catch (erro) {
console.error("Falha ao salvar (cancelamento ou erro):", erro);
}
}
salvarArquivoLocal();
Web Share API para compartilhar conteúdo no celular
A Web Share API permite acionar o compartilhamento nativo do sistema, comum em navegadores móveis. Ela envia dados como título, texto e URL para os apps disponíveis no dispositivo. Por design, normalmente funciona melhor em mobile e exige contexto seguro. O método navigator.share retorna uma Promise, permitindo detectar sucesso ou cancelamento.
O exemplo abaixo compartilha o título e a URL atual. Em aplicações reais, é comum validar suporte com navigator.canShare quando arquivos também podem ser compartilhados. Também é importante tratar o caso de cancelamento sem tratar como erro crítico. O trecho mostra um fluxo básico com fallback de log em caso de não suporte.
// Compartilhamento nativo com Web Share API
async function compartilharPagina() {
if (!navigator.share) {
console.error("Web Share API não suportada neste navegador.");
return;
}
try {
await navigator.share({
title: "Meu site",
url: location.href
});
console.log("Compartilhamento concluído.");
} catch (erro) {
console.error("Compartilhamento cancelado ou falhou:", erro);
}
}
compartilharPagina();
Performance API para medir tempos e obter métricas
A Performance API oferece ferramentas para medir tempo com alta resolução e inspecionar métricas de carregamento. O método performance.now() retorna um tempo em milissegundos com precisão superior ao Date.now, ideal para medir duração de operações. Também existem entradas de performance (PerformanceEntry) para navegação e recursos, dependendo do nível de acesso permitido. Isso ajuda a entender gargalos e a comparar melhorias.
O exemplo abaixo mede o tempo de execução de um bloco de código. Em aplicações maiores, também é comum usar performance.mark e performance.measure para medições nomeadas. Outro cuidado é medir com consistência, repetindo e descartando aquecimentos quando aplicável. O trecho demonstra medição simples e legível.
// Medição simples com Performance API
function medirOperacao() {
const inicio = performance.now();
// Operação simulada
let soma = 0;
for (let i = 0; i < 1_000_000; i++) soma += i;
const fim = performance.now();
console.log("Tempo (ms):", (fim - inicio).toFixed(2), "Soma:", soma);
}
medirOperacao();
Panorama coerente das APIs e limites práticos
O conjunto apresentado cobre desde comunicação e armazenamento até recursos de hardware e experiência do sistema. Algumas APIs são amplamente suportadas e estáveis, como Fetch, Web Storage, Intersection Observer e WebSocket. Outras são mais sensíveis a permissões e políticas, como Geolocation, MediaDevices, Notifications e Push. E há APIs com suporte limitado, como Web NFC e File System Access.
No caso de RFID, a realidade prática costuma exigir integração por hardware dedicado e software nativo ou camadas intermediárias, enquanto o NFC é o caminho mais próximo quando se busca algo diretamente do navegador. Com essa visão completa, as APIs deixam de ser “recursos soltos” e passam a formar um mapa claro de capacidades, restrições e aplicações típicas. O resultado é uma base sólida para compreender o que a Web consegue acessar e como estruturar integrações de forma segura e previsível. A combinação adequada dessas interfaces sustenta aplicações modernas, ricas e alinhadas às regras do ambiente do navegador.