- Aprender
- Computação e TI
- Programação
- Programação em JavaScript
- Fetch e APIs do navegador
Fetch e APIs do navegador: busca de dados
fetch, exibir os resultados em uma página web e manter pequenas quantidades de dados no navegador. Você lê requisições e respostas HTTP e dados JSON, trata estados de carregamento e erro e formata datas e preços de uma API para cada leitor. Você descobre por que ocorrem erros de CORS e por que chaves de API secretas não devem ficar no código de front-end. Depois, usa localStorage, sessionStorage e recursos do navegador, como geolocalização e a área de transferência.BásicoAula 8 de 9 do curso Curso de Programação em JavaScript
O que você vai aprender
- Explicar como funcionam uma requisição e uma resposta HTTP, carregar dados JSON com
fetche enviar dados a uma API com o método, os cabeçalhos e o corpo adequados.- Ler requisições e respostas HTTPDescrever as partes de uma requisição e de uma resposta HTTP, relacionar cada método HTTP à ação que ele executa e ler códigos de status e cabeçalhos nas ferramentas de desenvolvimento do navegador.
- Carregar dados JSON com fetchChamar
fetch, verificar o status da resposta, ler e analisar o corpo JSON e construir URLs de requisição com parâmetros de consulta codificados corretamente. - Enviar dados com POST, PUT, PATCH e DELETEPassar um objeto de opções para
fetchpara enviar JSON ou dados de formulário e tratar a resposta do servidor após criar, atualizar ou excluir um registro.
- Ler requisições e respostas HTTP
- Transformar resultados de APIs em conteúdo de página, formatar datas e valores monetários para o leitor e manter a página clara enquanto os dados carregam, falham ou chegam fora de ordem.
- Renderizar resultados de APIs na páginaConstruir elementos de página a partir dos vetores e objetos de uma resposta JSON, inserir texto de APIs com segurança e tratar campos ausentes, resultados vazios e resultados paginados.
- Formatar datas, números e valores monetários a partir de dados de APIsConverter as cadeias de caracteres de datas, marcas de tempo e quantias enviadas por APIs em texto legível para o idioma, a região e o fuso horário do leitor com os formatadores
Intl. - Exibir estados de carregamento, erro e ausência de dadosAcompanhar as etapas de uma requisição, mostrar ao usuário uma mensagem clara para cada etapa e recuperar-se de falhas com novas tentativas.
- Cancelar requisições, definir limites de tempo e combinar requisiçõesCancelar requisições que não são mais necessárias, definir limites de tempo, impedir que respostas antigas substituam as mais recentes e executar várias requisições em paralelo ou em sequência.
- Renderizar resultados de APIs na página
- Explicar a política de mesma origem e os erros de CORS e proteger chaves de API e dados dos usuários quando uma página se comunica com outros servidores.
- Compreender a política de mesma origem e o CORSIdentificar a origem de uma URL, explicar por que o navegador bloqueia algumas respostas de outras origens e reconhecer como cabeçalhos CORS e requisições de verificação prévia permitem que um servidor as autorize.
- Proteger chaves de API e dados dos usuáriosExplicar o que fazem chaves de API e tokens, por que um segredo no código de front-end é público e como enviar credenciais e tratar dados dos usuários com responsabilidade.
- Compreender a política de mesma origem e o CORS
- Salvar, ler e atualizar pequenas quantidades de dados com localStorage e sessionStorage e decidir o que é razoável e seguro manter no navegador.
- Salvar e ler dados com localStorage e sessionStorageUsar os métodos do armazenamento web, explicar por quanto tempo cada tipo de armazenamento dura e quem pode lê-lo e converter números, booleanos e objetos em cadeias de caracteres armazenadas e vice-versa.
- Usar o armazenamento do navegador em uma aplicaçãoRestaurar o estado salvo quando uma página carrega, armazenar respostas de APIs em cache com um prazo de expiração, manter abas sincronizadas e decidir o que não deve ser armazenado.
- Salvar e ler dados com localStorage e sessionStorage
- Detectar e usar APIs do navegador que precisam de uma página segura ou da permissão do usuário, como geolocalização e a área de transferência, e oferecer aos usuários uma alternativa quando um recurso estiver indisponível.
- Obter a localização do usuário com a API de GeolocalizaçãoVerificar se uma API do navegador está disponível, explicar contextos seguros e solicitações de permissão e usar a API de Geolocalização com suas opções, erros e uma alternativa.
- Copiar texto e usar outras APIs do navegadorCopiar texto com a API da área de transferência, reagir a mudanças de conectividade, ler parâmetros do endereço da página e seguir um método para aprender qualquer nova API do navegador.
- Obter a localização do usuário com a API de Geolocalização
Guia de estudo de Fetch e APIs do navegador
1Fazer requisições e ler as respostas
Uma página pode pedir dados a um servidor sem carregar uma nova página. A requisição diz qual recurso você quer e o que quer fazer com ele; a resposta informa o que aconteceu. Você acompanhará essa troca na aba Network, transformará uma resposta JSON em dados JavaScript e enviará alterações de volta ao servidor. Os pontos principais a verificar são o método, o status e a estrutura do corpo: a chegada de uma resposta, por si só, não significa que a operação foi bem-sucedida.
1.1 As partes de uma troca HTTP
Uma API web permite que um programa leia ou altere dados por meio de URLs identificadas chamadas pontos de acesso da API. O JavaScript na página é o cliente. Ele envia uma requisição HTTP; o servidor responde com uma resposta HTTP. Muitas APIs enviam texto JSON, que pode representar objetos, vetores, cadeias de caracteres, números, booleanos e null.
Ler uma requisição
Considere GET https://api.example.com/books?author=Le%20Guin&limit=5. O método é GET, o caminho /books seleciona o recurso e a cadeia de consulta contém dois parâmetros. O valor de author é “Le Guin”; %20 codifica o espaço. Um e comercial separa os parâmetros. A documentação da API explica quais nomes de parâmetros ela aceita e o que cada valor significa.
Uma requisição também pode conter cabeçalhos, que são pares de nome e valor, e um corpo, que contém os dados enviados. Accept: application/json solicita uma resposta JSON. Content-Type: application/json descreve o corpo enviado. Authorization transporta credenciais. Nomes de cabeçalhos não diferenciam maiúsculas de minúsculas, então content-type e Content-Type identificam o mesmo cabeçalho.
Escolher a ação
| Método | Ação pretendida | Uso típico |
|---|---|---|
GET | Ler | Obter uma lista de notas |
POST | Criar ou enviar | Adicionar uma nota |
PUT | Substituir | Enviar a nota completa para substituição |
PATCH | Alterar parte | Marcar uma nota como concluída |
DELETE | Remover | Excluir uma nota |
GET e HEAD são métodos seguros: sua finalidade é a leitura, então não use GET para um botão de exclusão. GET, PUT e DELETE são idempotentes. Repetir a mesma requisição deixa o servidor no mesmo estado pretendido que executá-la uma vez. Excluir uma nota já excluída pode retornar um status diferente, mas a nota continua ausente. Repetir um POST pode criar um segundo registro.
Interpretar a resposta
A resposta contém um código de status, cabeçalhos e geralmente um corpo. O primeiro dígito agrupa o resultado:
- 2xx: sucesso.
200 OKgeralmente contém dados,201 Createdinforma uma criação e204 No Contentnão tem corpo. - 3xx: redirecionamento. Por padrão,
fetchsegue redirecionamentos. - 4xx: um problema com a requisição ou o acesso.
400significa requisição inválida;401significa credenciais ausentes ou inválidas;403significa que o servidor entende a requisição, mas a recusa;404significa que o recurso não foi encontrado;429significa requisições em excesso. - 5xx: um problema no servidor, como
500 Internal Server Errorou503 Service Unavailable.
Uma chamada a /books/42 pode retornar 200, um tipo de conteúdo JSON e {"id":42,"title":"The Dispossessed","year":1974}. Uma chamada a /books/9999 pode retornar 404 e {"error":"Book not found"}. Ambas as chamadas receberam uma resposta. Uma falha de conexão não produz um status HTTP para o JavaScript inspecionar.
Inspecionar antes de supor
Abra as ferramentas de desenvolvimento, selecione Network e acione a operação. Inspecione o método, a URL completa, o status, os cabeçalhos, o corpo e os tempos. Compare-os com o ponto de acesso, os parâmetros obrigatórios, as credenciais, os limites de requisições por período e a resposta de exemplo da documentação. Se o servidor retornou os dados corretos, investigue o código da página; se a URL da requisição estiver errada, corrija-a antes de alterar a função de renderização.
Principais conclusões
- Um ponto de acesso é uma URL que uma API disponibiliza para uma operação.
- O método seleciona a ação; a URL seleciona o recurso e os parâmetros.
- Os cabeçalhos da requisição e da resposta descrevem a troca.
- Um
404é uma resposta, enquanto uma falha de conexão não tem status HTTP. - Inspecione a aba Network e compare a troca com a documentação da API.
1.2 Carregar JSON em duas etapas assíncronas
fetch(url) envia uma requisição GET e retorna uma promessa. Seu resultado é um objeto Response, disponível quando os cabeçalhos chegam. Ler o corpo é uma operação assíncrona separada. response.json() lê esse corpo e o analisa, transformando-o em dados JavaScript.
Aguardar, verificar, ler
async function loadBook(id) {
const response = await fetch(`https://api.example.com/books/${id}`);
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return await response.json();
}
Para loadBook(42), o primeiro await obtém a resposta. A condição rejeita um resultado HTTP malsucedido. O segundo await obtém os dados analisados do livro, como { id: 42, title: "The Dispossessed", year: 1974 }. A própria função retorna uma promessa, então quem a chama também aguarda o resultado.
response.ok é verdadeiro para status de 200 a 299. Um erro HTTP como 404 ou 500 não rejeita a promessa de fetch: um servidor respondeu. Uma falha de rede, uma troca bloqueada por CORS, uma URL de requisição inválida ou um cancelamento podem rejeitá-la. Lançar um erro para !response.ok permite que um try/catch envolvente também trate falhas HTTP.
Entender o corpo
Sem await, const data = response.json() armazena uma promessa, não o livro. Acessar data.title então resulta em undefined. Omitir await de fetch também deixa uma promessa onde o código espera um Response.
Escolha o leitor de corpo adequado para a resposta: json() para JSON, text() para texto ou blob() para dados binários. Um corpo só pode ser consumido uma vez. Armazene o resultado analisado e reutilize-o. Para inspecionar também o texto JSON bruto, leia text() uma vez e chame JSON.parse(text) nessa cadeia armazenada.
Um JSON inválido causa uma rejeição com SyntaxError. Uma página de erro em HTML frequentemente causa uma mensagem “Unexpected token '<'”. Um corpo vazio, incluindo uma resposta 204, também não pode ser analisado como JSON. Verifique primeiro o status e inspecione response.headers.get("Content-Type") quando houver dúvida sobre o formato. Um status de sucesso, por si só, não garante um corpo JSON.
Construir uma consulta com segurança
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", "rock & roll");
url.searchParams.set("limit", 10);
O endereço resultante é https://api.example.com/search?q=rock+%26+roll&limit=10. O e comercial no valor é codificado como parte dele. Concatenar a entrada a "?q=" pode fazer &, # ou + assumirem seus significados em URLs e alterar a busca. Uma URL relativa segue a resolução normal de endereços: a partir de https://notes.example.org/app/index.html, fetch("data/books.json") carrega /app/data/books.json nessa origem.
Acompanhar a estrutura retornada
Para {"results":[{"title":"Dune"}],"total":1}, o primeiro título é data.results[0].title. O objeto externo não é o vetor de resultados. Use a prévia da resposta para encontrar o vetor antes de percorrê-lo.
Uma função auxiliar compartilhada getJSON(url, options) pode executar a mesma verificação de status e leitura do corpo para várias chamadas. Em uma cadeia .then(), retorne response.json() da função de retorno da resposta para que a próxima receba os dados analisados. Adicione .catch() ao final para tratar etapas rejeitadas.
Principais conclusões
fetcheresponse.json()retornam promessas separadas.- Verifique
response.ok; um erro HTTP não fazfetchser rejeitada. - Leia o corpo de uma resposta uma vez e reutilize o valor armazenado.
- Use
URL.searchParamspara codificar valores de consulta. - Leia o JSON aninhado de acordo com sua estrutura real de objetos e vetores.
- Uma resposta bem-sucedida ainda pode conter um corpo JSON vazio ou inválido.
1.3 Enviar uma alteração e usar o resultado do servidor
O segundo argumento de fetch configura uma requisição. Suas opções incluem method, headers, body, signal e credentials. Sem essas opções, a requisição é um GET sem corpo. Para enviar JSON, você precisa preparar tanto seu texto quanto seu tipo de conteúdo.
Enviar JSON
const response = await fetch("https://api.example.com/notes", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "Shopping", text: "Rice, lentils" }),
});
JSON.stringify produz {"title":"Shopping","text":"Rice, lentils"}. O cabeçalho informa ao servidor como ler esse texto. Passar o objeto diretamente como corpo envia "[object Object]". Enviar a cadeia JSON sem o cabeçalho identifica-a como text/plain;charset=UTF-8, que muitos pontos de acesso JSON rejeitam com 400 ou 415 Unsupported Media Type.
Uma criação bem-sucedida frequentemente retorna 201 com o registro armazenado, como {"id":17,"title":"Shopping","text":"Rice, lentils"}. Use esse objeto retornado para atualizar a página: o novo id do servidor é necessário para edições e exclusão posteriores.
Substituir ou atualizar
| Requisição | Corpo | Significado |
|---|---|---|
PATCH /notes/17 | {"done":true} | Alterar o campo fornecido |
PUT /notes/17 | A nota completa para substituição | Substituir o recurso |
DELETE /notes/17 | Frequentemente nenhum | Remover o recurso |
Um corpo de PUT que omite um campo pode fazer com que esse campo seja removido ou redefinido, de acordo com a API. Use o método documentado para a alteração pretendida. PUT e PATCH podem retornar um registro atualizado com 200 ou retornar 204 sem corpo.
Trate o sucesso sem supor que sempre haverá JSON:
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
const saved = response.status === 204
? null
: await response.json();
Esse padrão serve para pontos de acesso documentados para retornar JSON ou 204. Uma exclusão pode ser bem-sucedida e ainda produzir um erro de análise sintática se o código chamar json() no corpo vazio sem verificar.
Escolher o formato do corpo
new FormData(formElement) coleta campos nomeados de formulário e arquivos selecionados. Passe-o diretamente como body. Deixe o navegador definir Content-Type: multipart/form-data e seu delimitador; um cabeçalho fornecido manualmente pode omitir o delimitador necessário para separar os campos. Um corpo URLSearchParams usa application/x-www-form-urlencoded.
GET e HEAD não podem transportar um corpo por meio de fetch. Coloque termos de busca e filtros na cadeia de consulta da URL. Tentar um GET com corpo resulta em rejeição com um TypeError antes que ele possa servir como requisição de busca.
Finalizar com segurança após sucesso ou falha
Desabilite o botão de envio antes de aguardar uma requisição de criação e habilite-o novamente em finally. Caso contrário, um clique duplo pode enviar duas requisições POST e criar dois registros. Não repita automaticamente uma operação de criação cujo resultado seja incerto: uma resposta perdida não confirma se o servidor fez a alteração.
Para um status de erro, o corpo pode conter uma mensagem útil como {"error":"title is required"}. Leia-o uma vez se for JSON; capture uma falha de análise sintática e mantenha uma mensagem HTTP geral para respostas vazias ou em HTML. Mantenha disponível o texto digitado pelo usuário para que ele possa corrigir a requisição.
Principais conclusões
- Requisições JSON precisam de
JSON.stringifye de um tipo de conteúdo correspondente. - Use
PATCHpara uma alteração parcial ePUTpara uma substituição completa. - Não analise o corpo como JSON para
204 No Content. - Deixe o navegador definir o cabeçalho multipart ao enviar
FormData. - Use a resposta do servidor, incluindo o ID atribuído, para atualizar a página.
- Impeça envios duplicados e restaure os controles em
finally.
2Transformar respostas em uma página útil
Buscar dados é apenas a primeira parte de uma interface. Os leitores precisam de resultados úteis, datas e preços legíveis e uma mensagem clara enquanto aguardam. Você construirá a exibição a partir da estrutura da resposta, impedirá que valores ausentes a interrompam e tornará visíveis o sucesso, os resultados vazios e as falhas. Você também controlará requisições sobrepostas para que uma resposta lenta não substitua resultados mais recentes e escolherá quando requisições independentes podem ser executadas juntas.
2.1 Construir a exibição a partir de dados
A renderização transforma um vetor ou objeto em elementos na página. Mantenha os dados obtidos em uma variável e passe-os para uma função de renderização. Essa separação permite ordenar ou filtrar os mesmos dados sem pedi-los novamente ao servidor.
Criar um elemento por item
function renderBooks(books, list) {
list.replaceChildren();
for (const book of books) {
const item = document.createElement("li");
item.textContent = `${book.title} (${book.year})`;
list.append(item);
}
}
Para [{"title":"Kindred","year":1979},{"title":"Beloved","year":1987}], isso cria dois itens de lista: “Kindred (1979)” e “Beloved (1987)”. Limpar o contêiner primeiro faz uma nova busca substituir a anterior. Sem essa etapa, as listas antiga e nova se acumulam.
Manter texto externo como texto
Use textContent para títulos, descrições e outros textos de APIs. innerHTML analisa uma cadeia como marcação. Um título que contém <img src="x" onerror="alert(1)"> pode então executar código. Isso é injeção de scripts entre sites, ou XSS. Textos de formulários e do armazenamento precisam do mesmo tratamento, pois também podem ter vindo de uma fonte não confiável.
Propriedades de elementos definem valores individuais, como img.alt = book.title. Elas não tornam automaticamente todos os tipos de valor seguros. Um link fornecido por uma API ainda precisa de uma verificação de protocolo:
try {
const target = new URL(book.url, location.href);
if (target.protocol === "https:" || target.protocol === "http:") {
link.href = target.href;
}
} catch {
link.removeAttribute("href");
}
Esse código é executado em um link recém-criado sem um href existente. Uma URL inválida ou não permitida deixa-o sem destino. Uma URL javascript: não é uma navegação web comum. Para imagens, forneça um texto alt significativo construído a partir dos dados quando possível.
Fornecer valores padrão sem perder valores reais
Campos opcionais podem estar ausentes ou ser null. book.author?.name ?? "Unknown author" primeiro tenta obter o nome aninhado e depois fornece um valor padrão. O encadeamento opcional evita acessar uma propriedade de um autor ausente.
O operador importa: 0 || "n/a" fornece "n/a", enquanto 0 ?? "n/a" mantém 0. O operador || substitui todos os valores avaliados como falsos, incluindo zero e uma cadeia vazia; ?? substitui apenas null e undefined. Um livro com zero exemplares disponíveis precisa exibir zero.
Um vetor de resultados vazio é uma busca bem-sucedida sem correspondências. Mostre “Nenhum livro corresponde à sua busca.” para que os leitores possam distingui-la de uma página que não carregou.
Substituir uma busca, adicionar outra página
Muitas APIs retornam páginas usando page, limit, uma contagem total ou uma URL next. Com 47 resultados e 10 por página, quatro páginas completas contêm 40 registros e a quinta contém 7. Uma nova busca limpa a lista anterior; “Carregar mais” adiciona a próxima página à lista atual. Mantenha essas duas ações de exibição separadas.
Para ordenar uma cópia local com os mais recentes primeiro, use [...books].sort((a, b) => b.year - a.year) e renderize essa cópia. O espalhamento cria um novo vetor, então a ordem salva da resposta continua disponível. Inspecione a estrutura da resposta antes de selecionar o vetor: uma API paginada frequentemente o coloca dentro de data.results.
Principais conclusões
- Renderize a partir de dados salvos para que a ordenação local não precise de uma nova requisição.
- Insira texto não confiável com
textContent. - Valide o protocolo de um link de API antes de atribuir seu destino.
- Use
?.para dados aninhados ausentes e??quando zero precisar permanecer zero. - Substitua os resultados para uma nova busca; adicione resultados para outra página.
2.2 Formatar datas e quantias para as pessoas
APIs retornam valores fáceis de trocar entre programas. Os leitores precisam de datas, horários e quantias formatados para seu idioma e sua região. Mantenha o valor armazenado separado do texto usado para exibi-lo.
Ler primeiro o formato da data
"2026-03-05T14:30:00Z" identifica um instante: 14:30 UTC de 5 de março de 2026. O Z significa UTC. new Date(...) transforma-o em um Date JavaScript. Uma cadeia apenas com data, como "2026-03-05", é interpretada como meia-noite UTC; uma data e hora sem deslocamento, como "2026-03-05T14:30", é interpretada como horário local.
Uma marca de tempo Unix conta a partir de 1 de janeiro de 1970, UTC. APIs frequentemente contam segundos, mas Date recebe milissegundos. new Date(1772721000 * 1000) fornece o mesmo instante de 5 de março. Omitir a multiplicação resulta em uma data em janeiro de 1970. Leia a documentação da API para identificar a unidade.
Escolher uma configuração regional e um fuso horário
const date = new Date("2026-03-05T14:30:00Z");
const dateFormat = new Intl.DateTimeFormat("en-US", {
dateStyle: "medium",
timeStyle: "short",
timeZone: "UTC",
});
dateFormat.format(date);
A saída é “Mar 5, 2026, 2:30 PM”. Com en-GB, é “5 Mar 2026, 14:30”. Usar datas curtas produz “3/5/26” em en-US, “05/03/2026” em en-GB e “05.03.26” em de-DE.
A configuração regional controla a apresentação; o fuso horário controla a hora local. Sem um timeZone, o formatador usa o fuso do dispositivo. Esse instante corresponde a 9:30 da manhã em Nova York, 15:30 em Amsterdã e 11:30 da noite em Tóquio. Mantenha e envie instantes em UTC e converta-os para exibição. Uma data de calendário, como um aniversário, exige cuidado: formatar meia-noite UTC em um fuso a oeste de UTC pode mostrar o dia anterior.
Manter a moeda separada da configuração regional
const priceFormat = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "EUR",
});
priceFormat.format(1234.5);
Isso fornece €1,234.50. Para a mesma quantia, de-DE com EUR fornece 1.234,50 €; en-US com USD fornece $1,234.50; en-US com JPY fornece ¥1,235. JPY não tem subunidade monetária, então sua exibição normal não tem casas decimais. Selecionar uma configuração regional não converte moedas. Use o código de moeda fornecido com a quantia.
Algumas APIs de pagamento enviam subunidades monetárias inteiras. Com USD, 1999 centavos significam 19.99 dólares: divida por 100 antes de formatar. Não aplique esse divisor a JPY. Somar centavos inteiros resulta em 1999 + 2550 = 4549, que é formatado como $45.49. Isso evita o conhecido resultado da aritmética decimal 0.1 + 0.2, que é 0.30000000000000004.
Reutilizar o formatador
Crie um formatador uma vez para uma lista. Use undefined como sua configuração regional para selecionar o padrão do navegador; navigator.language informa a identificação do idioma preferido do navegador. Outras opções formatam 0.256 como “26%” ou 12.5 com a unidade "kilometer-per-hour" como “12.5 km/h”. new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(-1, "day") fornece “yesterday”. Datas montadas manualmente, como “03/05/2026”, continuam ambíguas entre regiões.
Principais conclusões
- Verifique se as marcas de tempo usam segundos ou milissegundos.
- Um fuso horário explícito torna previsível a exibição de data e hora.
- A configuração regional controla a formatação; a moeda vem dos dados.
- Converta as subunidades monetárias documentadas antes de formatar valores monetários.
- Reutilize objetos formatadores
Intlem uma lista. - Cadeias apenas com data são interpretadas como UTC e podem mudar de dia quando exibidas em outro fuso.
2.3 Mostrar o que a requisição está fazendo
Uma requisição tem um ciclo de vida visível: inativa, carregando e, em seguida, sucesso ou erro. O sucesso pode conter dados ou um resultado vazio. A página deve explicar cada estado para que os leitores saibam se devem esperar, alterar uma busca ou tentar novamente.
Manter a preparação e a limpeza juntas
Nesse tratador, getJSON verifica o status HTTP e analisa o corpo, searchUrl constrói a URL da requisição e renderResults atualiza a lista. O botão e o elemento de status já existem na página.
async function search(query) {
button.disabled = true;
status.textContent = "Loading…";
try {
const data = await getJSON(searchUrl(query));
renderResults(data.results);
status.textContent = data.results.length === 0 ? "No results." : "";
} catch (error) {
status.textContent = "Could not load results. Check your connection and try again.";
console.error(error);
} finally {
button.disabled = false;
}
}
A preparação acontece antes da espera. O caminho de sucesso renderiza os resultados e trata um vetor vazio. O bloco catch substitui a mensagem de carregamento se qualquer etapa aguardada falhar. finally restaura o botão após qualquer um dos caminhos. Se a limpeza ocorresse apenas após um await bem-sucedido, uma falha deixaria o controle desabilitado.
Explicar a causa de forma útil
Um erro HTTP tem um status que orienta a mensagem. Para 404, diga que o item não foi encontrado. Para 401, peça ao usuário que entre na conta; para 403, explique que o acesso não é permitido. Para 429, peça que aguarde. Para 5xx, explique que o serviço está com um problema e sugira tentar mais tarde.
Um TypeError de fetch pode significar uma falha de rede, uma requisição bloqueada por CORS ou uma URL inválida. O JavaScript não recebe um diagnóstico detalhado e confiável de CORS; inspecione o console do navegador e a aba Network. Um SyntaxError de json() indica JSON inválido. Cancelamentos e limites de tempo produzem erros como AbortError e TimeoutError. Mantenha os detalhes técnicos no console e ofereça aos leitores uma ação que possam entender.
Tornar as mudanças perceptíveis
Use um elemento de status existente, como <p role="status"></p>. Suas alterações são anunciadas aos leitores de tela sem mover o foco. aria-live="polite" tem uma finalidade semelhante; role="alert" é adequado para erros urgentes. Um indicador de carregamento sozinho não comunica um resultado vazio ou uma requisição malsucedida.
Um botão Tentar novamente chama a função de carregamento outra vez. Repetir requisições 400 ou 404 sem alterações geralmente repete o problema. Falhas temporárias de rede ou do serviço podem justificar uma pequena sequência limitada de novas tentativas. A espera exponencial entre tentativas aumenta a pausa, por exemplo, 1 segundo, 2 segundos e depois 4 segundos. Respeite o cabeçalho de resposta Retry-After; ele pode informar uma espera em segundos ou uma data HTTP. Evite repetir automaticamente uma requisição de criação que talvez já tenha sido bem-sucedida.
Se uma atualização falhar, mas os dados anteriores ainda forem úteis, mantenha-os visíveis com uma nota como “Exibindo resultados das 10:42. Não foi possível atualizar.” Não faça resultados antigos parecerem atuais sem avisar.
Testar os caminhos difíceis
Use as ferramentas de desenvolvimento para tornar a conexão lenta, ficar offline e requisitar um caminho inexistente. Verifique se o carregamento aparece rapidamente, se uma requisição malsucedida o substitui, se um sucesso vazio tem sua própria mensagem e se os controles voltam a ficar utilizáveis.
Principais conclusões
- Torne visíveis o carregamento, o sucesso vazio, o sucesso com dados e os erros.
- Coloque a limpeza compartilhada em
finally. - Ofereça aos leitores uma ação útil e mantenha os detalhes técnicos no console.
- Anuncie atualizações de status por meio de uma região dinâmica apropriada.
- Limite as novas tentativas e respeite a espera solicitada pelo servidor.
2.4 Controlar requisições sobrepostas e paralelas
Requisições podem continuar depois da ação que as iniciou. Uma resposta de busca pode chegar depois que o leitor digitou outra coisa, e um serviço lento pode deixar uma página esperando por tempo demais. Controle quais resultados ainda são relevantes, além de verificar se cada requisição foi bem-sucedida.
Cancelar o trabalho que não é mais necessário
Crie um AbortController, passe seu signal para fetch e chame abort() para cancelar a requisição. O cancelamento pode interromper tanto a espera pelos cabeçalhos quanto uma leitura do corpo em andamento. A rejeição normalmente se chama "AbortError".
const controller = new AbortController();
const response = await fetch(url, { signal: controller.signal });
// A cancel button can call controller.abort().
const data = await response.json();
Envolva os dois usos de await no tratamento de erros. Se seu código cancelar intencionalmente uma busca antiga, retorne silenciosamente para esse cancelamento esperado, em vez de dizer ao usuário que o serviço falhou.
fetch não tem uma opção timeout nativa. Use um sinal como AbortSignal.timeout(5000) para limitar a requisição a 5000 ms, ou 5 segundos de tempo ativo. Antes da chegada dos cabeçalhos, ela é rejeitada com TimeoutError; depois que os cabeçalhos chegam, o sinal pode interromper a leitura do corpo.
Impedir que buscas antigas prevaleçam
Uma condição de corrida ocorre quando a ordem de conclusão altera o resultado. Um leitor digita “ca” e depois “cat”. Se “ca” retornar por último e for renderizado, a tela deixará de corresponder à entrada.
Uma abordagem cancela a requisição anterior antes de cada nova requisição. Outra atribui um número a cada chamada e permite que apenas a mais recente atualize a página:
let latest = 0;
async function search(query) {
const request = ++latest;
try {
const data = await getJSON(searchUrl(query));
if (request !== latest) return;
renderResults(data.results);
} catch (error) {
if (request !== latest) return;
showError(error);
}
}
A verificação também impede que uma falha antiga substitua um sucesso mais recente. Aplique a mesma verificação de relevância às mensagens de carregamento e à restauração dos controles quando as chamadas se sobrepuserem.
O adiamento até cessarem os eventos reduz a quantidade de chamadas iniciadas. Cancele o temporizador anterior a cada tecla pressionada e inicie outro, por exemplo, de 300 ms. Digitar “paris” rapidamente inicia então uma requisição após a pausa. Esse adiamento economiza requisições; por si só, ele não impede que uma resposta anterior ainda em andamento chegue atrasada.
Decidir o que pode ser executado em conjunto
Requisições independentes podem começar juntas:
const [user, posts] = await Promise.all([
getJSON(userUrl),
getJSON(postsUrl),
]);
Para durações de 300 ms e 500 ms, as duas levam cerca de 500 ms, em vez de cerca de 800 ms em sequência. Promise.all é rejeitado assim que uma entrada é rejeitada, mas não cancela as outras operações.
Use Promise.allSettled quando resultados parciais forem úteis. Ele aguarda todas as entradas e informa cada resultado como { status: "fulfilled", value } ou { status: "rejected", reason }. Um painel pode então mostrar seções bem-sucedidas ao lado de uma que falhou.
Requisições dependentes precisam permanecer em sequência. Se uma segunda URL precisar de um ID retornado pela primeira requisição, aguarde esse ID antes de construir a segunda requisição.
Principais conclusões
- Passe um sinal de cancelamento antes de chamar
abort(). - Capture erros tanto da busca quanto da leitura do corpo.
- Ignore resultados e erros antigos.
- O adiamento até cessarem os eventos reduz chamadas; uma verificação de relevância impede atualizações antigas.
- Use
Promise.allpara operações independentes que precisam ser bem-sucedidas em conjunto. - Use
Promise.allSettledquando resultados parciais forem úteis. - Aguarde os dados necessários antes de iniciar uma requisição dependente.
3Ler dados de outras origens e proteger credenciais
Uma requisição pode parecer correta e ainda falhar em um navegador porque a página e a API pertencem a origens diferentes. Esse limite é controlado em conjunto pelas regras do navegador e pelos cabeçalhos de resposta do servidor. Você identificará a origem, interpretará falhas de verificação prévia e de CORS e distinguirá a permissão para ler uma resposta da permissão para executar uma ação. As credenciais exigem uma decisão separada: tudo o que é entregue a um navegador pode ser inspecionado por seu usuário.
3.1 Compreender o limite de origem do navegador
Uma origem combina o esquema, o host e a porta de uma URL. O caminho não faz parte dela. https://shop.example.com/cart e /help no mesmo site compartilham uma origem. Mudar para http://shop.example.com, https://api.example.com ou https://shop.example.com:8443 altera a origem. HTTPS normalmente usa a porta 443.
Quem permite a leitura da resposta?
A política de mesma origem limita quais recursos um script de página pode ler. Para uma busca em outra origem, o CORS permite que o servidor da API conceda acesso por meio de cabeçalhos de resposta. Uma página em https://notes.example.org que chama https://api.example.com/weather precisa da permissão da API para ler a resposta.
Access-Control-Allow-Origin: https://notes.example.org concede acesso a essa origem. O valor * permite qualquer origem para uma requisição sem credenciais. Se a resposta não tiver uma permissão correspondente, o navegador a oculta da página e fetch é rejeitada com um TypeError. O console fornece o diagnóstico de CORS; o JavaScript não recebe o motivo detalhado.
Adicionar Access-Control-Allow-Origin à requisição JavaScript não concede permissão. Ele é um cabeçalho de resposta controlado pelo servidor. Adicionar um cabeçalho personalizado à requisição pode gerar uma verificação prévia adicional.
Por que OPTIONS aparece antes de POST
Algumas requisições entre origens precisam de uma verificação prévia. O navegador envia primeiro OPTIONS, indicando o método pretendido em Access-Control-Request-Method e os nomes dos cabeçalhos que não constam da lista de segurança em Access-Control-Request-Headers. O servidor os permite com Access-Control-Allow-Methods e Access-Control-Allow-Headers, junto com a permissão para a origem.
Um GET, HEAD ou POST básico com apenas cabeçalhos permitidos pode evitar a verificação prévia. Os tipos de conteúdo permitidos incluem text/plain, application/x-www-form-urlencoded e multipart/form-data. Um POST com JSON, um cabeçalho Authorization, PUT ou DELETE exige verificação prévia, a menos que uma permissão anterior válida esteja em cache. Se a verificação prévia for recusada, a requisição real não será enviada.
Para uma requisição simples, a requisição real pode chegar ao servidor mesmo quando o navegador bloqueia posteriormente a leitura da resposta. Portanto, o CORS não substitui a autorização do servidor nem a verificação das entradas.
Cookies acrescentam outro requisito
O padrão credentials: "same-origin" envia cookies apenas para requisições da mesma origem. credentials: "include" também permite cookies elegíveis em requisições de outras origens. As regras SameSite dos cookies e as políticas para cookies de terceiros continuam em vigor.
Para permitir que o JavaScript leia uma resposta com credenciais, o servidor deve enviar Access-Control-Allow-Credentials: true e indicar explicitamente a origem da página. Access-Control-Allow-Origin: * não funciona com credenciais. Esses cabeçalhos não obrigam o navegador a enviar um cookie que seria bloqueado por outro motivo.
Diagnosticar sem ocultar o problema
mode: "no-cors" fornece uma resposta opaca com status 0 e sem corpo ou cabeçalhos legíveis. Ela não pode fornecer JSON a uma página. Uma requisição que funciona em curl também não comprova a permissão de CORS no navegador: clientes de terminal não aplicam essa política do navegador.
Inspecione o console e a aba Network. Verifique se a verificação prévia falhou ou se faltou permissão na resposta final. Corrija a configuração de resposta da API ou encaminhe a chamada pelo seu próprio servidor. Durante o desenvolvimento, sirva páginas de um servidor local: páginas file:// costumam ter origens opacas. Um servidor local ainda precisa de permissão de CORS ao chamar outra origem.
Principais conclusões
- Uma origem consiste em esquema, host e porta.
- Os cabeçalhos de resposta do servidor concedem permissão de leitura entre origens.
- A verificação prévia verifica o método e os cabeçalhos propostos antes da requisição real.
- O CORS pode ocultar uma resposta depois que uma requisição simples já foi processada.
- Respostas com credenciais exigem uma origem explícita e um cabeçalho de credenciais.
no-corsproduz uma resposta opaca, não um JSON legível.
3.2 Manter chaves secretas fora da página
Uma chave de API identifica uma aplicação que faz chamadas para fins de uso, limites e cobrança. Um token de acesso concede acesso para um usuário ou uma sessão. Quem possui uma credencial utilizável pode agir com a autoridade dela, então decida onde ela deve ficar antes de adicioná-la a uma requisição.
Cabeçalhos protegem a localização, não o segredo do usuário
Provedores podem exigir Authorization: Bearer <token>, X-API-Key: <key> ou um parâmetro de consulta como api_key. Siga a documentação da API. Um cabeçalho evita colocar a credencial em uma URL completa que pode entrar em registros e ferramentas de análise. Um cabeçalho Authorization ou personalizado em uma chamada de outra origem normalmente provoca uma verificação prévia.
Um cabeçalho continua visível nas ferramentas de desenvolvimento. Visitantes podem inspecionar o JavaScript que baixam e as requisições que ele envia. Minificar o código ou ocultar um valor atrás de uma variável não o torna secreto.
Acompanhar a chave em uma requisição de previsão do tempo
Suponha que o código do navegador chame https://api.weather.example/v1/current?city=Lima&key=sk_live_4f9a2c. Qualquer pessoa que abrir a aba Network pode copiar a chave e usar a cota da conta. Mover esse valor para uma variável de ambiente usada na geração da versão de distribuição não ajuda se a geração inseri-lo no JavaScript entregue à página.
Um segredo mantido no servidor muda o caminho:
- A página chama seu próprio site em
/api/weather?city=Lima. - O servidor desse site adiciona o segredo e entra em contato com o provedor de previsão do tempo.
- O servidor retorna os dados de previsão do tempo à página, mantendo o segredo fora da resposta.
O servidor ainda precisa controlar o acesso e o uso de seu ponto de acesso. Manter o segredo do provedor em um servidor não torna inofensivo o uso público ilimitado.
Alguns provedores emitem chaves para navegador destinadas a ser públicas. Aplique as restrições de domínio do provedor, limite as APIs permitidas e defina cotas de uso. Use uma chave dessa maneira apenas quando seu projeto documentado permitir; uma chave secreta de servidor não se torna uma chave para navegador ao receber uma restrição de domínio.
Responder à exposição
Mantenha arquivos de credenciais fora do controle de versão, por exemplo, listando .env em .gitignore. Isso impede que o arquivo seja incluído em um commit; não impede que a geração do front-end publique um valor incorporado ao código. Se uma chave for exposta, revogue-a e emita uma substituta. Removê-la do commit mais recente deixa o histórico anterior e quaisquer cópias intactos.
Proteger a troca e reduzir o desperdício
Use HTTPS para chamadas de API para que dados e credenciais sejam criptografados em trânsito. Uma chamada fetch de uma página HTTPS para uma API HTTP é bloqueada como conteúdo misto. A criptografia não impede que a pessoa que usa o navegador veja sua própria requisição.
Um limite de requisições por período restringe o uso, por exemplo, a 60 requisições por minuto. Chamadas acima do limite podem retornar 429 Too Many Requests. Armazene resultados adequados em cache, adie a busca até cessar a digitação e evite chamadas duplicadas. Se o servidor fornecer Retry-After, respeite a espera indicada em vez de repetir tentativas imediatamente.
A validação no cliente torna formulários mais fáceis de usar, mas qualquer pessoa pode chamar um ponto de acesso sem seu formulário. O próprio servidor deve validar requisições e autorizar ações. Ao exibir sua resposta, continue tratando cadeias de caracteres como texto não confiável e insira-as com textContent.
Principais conclusões
- Código e requisições entregues ao navegador expõem quaisquer credenciais que contenham.
- Uma chave secreta deve ficar no servidor que chama o provedor.
- Restrinja chaves públicas para navegador por domínio, API e cota.
- Revogue uma chave exposta; excluí-la do código atual é insuficiente.
- HTTPS criptografa os dados em trânsito, enquanto o servidor continua validando e autorizando requisições.
4Manter pequenas quantidades de estado no navegador
Uma configuração ou um rascunho pode sobreviver a um recarregamento sem uma nova requisição ao servidor. O armazenamento do navegador facilita isso, mas seus valores são cadeias de caracteres e sua duração depende do armazenamento escolhido. Você salvará e restaurará pequenas partes do estado, validará dados antigos antes de usá-los e dará um prazo de expiração aos resultados de APIs em cache. Você também decidirá quais dados devem ficar em outro lugar, pois o armazenamento local não é um cofre de segredos nem a única cópia segura de um trabalho importante.
4.1 Salvar cadeias de caracteres e restaurar seus tipos
O armazenamento web oferece dois armazenamentos de pares chave-valor: localStorage e sessionStorage. Eles usam os mesmos métodos, então a principal escolha é por quanto tempo os dados devem durar e quais abas devem compartilhá-los.
Escolher o tempo de vida
| Armazenamento | Tempo de vida | Compartilhamento |
|---|---|---|
localStorage | Sobrevive ao fechamento da aba e do navegador até ser removido ou limpo | Compartilhado por páginas da mesma origem |
sessionStorage | Sobrevive a recarregamentos durante a sessão da página na aba | Separado para cada aba e origem |
Fechar a aba encerra seu armazenamento de sessão. Uma página recém-aberta que tenha uma página de origem pode começar com uma cópia do armazenamento de sessão dessa página, mas alterações posteriores permanecem separadas. Evite usar o armazenamento de sessão como forma de manter informações secretas de scripts.
O armazenamento segue as origens. https://app.example.com não pode compartilhar seu armazenamento com http://app.example.com. Caminhos na mesma origem o compartilham, então um prefixo como "notes-app:settings" ajuda a manter distintas as chaves de várias aplicações.
Usar os métodos de armazenamento
localStorage.setItem("notes-app:theme", "dark");
const theme = localStorage.getItem("notes-app:theme");
localStorage.removeItem("notes-app:theme");
setItem cria ou sobrescreve uma entrada. getItem retorna seu valor como cadeia de caracteres ou null se ela estiver ausente. removeItem remove uma entrada. clear() remove todas as entradas dessa área de armazenamento para a origem, o que pode afetar outros recursos no mesmo site. length e key(index) permitem inspecionar as chaves.
Use esses métodos em vez de atribuições de propriedades como localStorage.theme = "dark". Chaves como "length" ou "key" podem entrar em conflito com membros nativos quando acessadas como propriedades.
Converter valores deliberadamente
Após localStorage.setItem("count", 5), a leitura fornece "5". Adicionar 1 diretamente cria "51". Number(localStorage.getItem("count")) + 1 produz 6.
Um booleano armazenado apresenta uma armadilha semelhante. setItem("darkMode", false) armazena "false", e uma cadeia não vazia é avaliada como verdadeira. Leia com localStorage.getItem("darkMode") === "true" quando essas forem as duas cadeias esperadas no armazenamento.
Objetos e vetores precisam de JSON:
localStorage.setItem("settings", JSON.stringify({
theme: "dark",
fontSize: 18,
}));
const settings = JSON.parse(localStorage.getItem("settings"))
?? { theme: "light", fontSize: 16 };
Sem serialização, um objeto comum torna-se "[object Object]". JSON.parse(null) fornece null, então o valor padrão cobre uma entrada ausente. Uma cadeia armazenada malformada ainda precisa de try/catch, e os dados analisados precisam de uma verificação de estrutura antes do uso.
Manter o volume de trabalho pequeno
Chamadas ao armazenamento web são síncronas: o JavaScript aguarda cada uma na thread principal. Use-o para configurações, um rascunho ou uma lista curta, não para grandes coleções ou arquivos. IndexedDB fornece armazenamento assíncrono para volumes maiores de dados estruturados.
Navegadores atuais geralmente permitem cerca de 5 MiB em cada área de armazenamento web por origem. Um armazenamento cheio pode fazer setItem lançar QuotaExceededError; o acesso também pode falhar devido às configurações de privacidade do navegador. Trate a falha sem impedir o restante da aplicação de funcionar. As ferramentas de desenvolvimento mostram os armazenamentos na aba Application do Chrome e do Edge ou na aba Storage do Firefox, onde excluir entradas ajuda a testar primeiras visitas.
Principais conclusões
- Escolha
localStoragepara configurações persistentes compartilhadas esessionStoragepara o estado da sessão da aba. - Áreas de armazenamento são separadas por origem.
getItemretorna uma cadeia de caracteres ounull.- Serialize objetos com JSON e restaure seus tipos ao ler.
- Trate falhas de armazenamento e mantenha pequenas as gravações síncronas.
4.2 Restaurar o estado e definir a expiração dos dados em cache
Uma aplicação geralmente carrega ao iniciar e salva ao alterar. Leia uma lista salva quando a página abrir, renderize-a e salve a lista atualizada após uma edição. O armazenamento do navegador é uma cópia de conveniência: ele pode estar ausente, danificado, desatualizado ou ter sido limpo.
Validar antes de restaurar
Esta função de carregamento espera um vetor salvo de cadeias de caracteres:
function loadTodos() {
try {
const value = JSON.parse(localStorage.getItem("todos"));
if (Array.isArray(value) && value.every(item => typeof item === "string")) {
return value;
}
} catch {
// Continue with an empty list if reading or parsing fails.
}
return [];
}
JSON.parse sozinho não comprova que o valor é um vetor ou que seus itens são adequados para a aplicação. Um JSON válido como 42 ainda tem a estrutura errada. Um valor com versão, como { version: 2, todos: [...] }, permite que o código mais recente reconheça formatos antigos e os converta ou restaure um valor padrão.
Salve a lista em memória com localStorage.setItem("todos", JSON.stringify(todos)) após cada alteração. Capture também falhas de gravação; uma página deve poder continuar funcionando mesmo quando não consegue preservar o estado para o próximo recarregamento. Um rascunho de formulário que pertence apenas a uma visita pode usar sessionStorage.
Adicionar uma marca de tempo às respostas em cache
localStorage.setItem("weather", JSON.stringify({
savedAt: Date.now(),
data,
}));
Em um carregamento posterior, valide primeiro a estrutura e a marca de tempo do objeto em cache. Sua idade é Date.now() - savedAt. Use-o apenas enquanto essa idade for inferior a 10 * 60 * 1000, ou 600.000 ms. Um valor salvo às 10:00:00 tem 450.000 ms de idade às 10:07:30 e pode ser usado. Às 10:12:00, tem 720.000 ms, então busque um valor atualizado. Com exatamente 600.000 ms, ele está expirado segundo essa regra.
A expiração é uma lógica da aplicação: localStorage não exclui uma entrada quando seu intervalo de validade termina. Rejeite uma marca de tempo ausente ou inválida em vez de tratar uma idade desconhecida como atual. Você pode manter dados antigos visíveis durante uma atualização malsucedida se eles estiverem identificados como antigos.
Sincronizar outras abas
Quando uma aba altera localStorage, outras abas da mesma origem recebem um evento storage. A aba que grava não recebe seu próprio evento. O evento disponibiliza key, oldValue, newValue e url.
window.addEventListener("storage", (event) => {
if (event.key === "theme") applyTheme(event.newValue);
});
Aplique o tema imediatamente também na aba que faz a gravação. Trate null quando uma chave for removida. Um evento storage não substitui a atualização do estado da sua própria página.
Decidir o que deve ficar em outro lugar
Não coloque senhas, números de cartão de pagamento ou chaves de API secretas no armazenamento web. Scripts da origem podem lê-lo, incluindo código de terceiros e scripts injetados. Limpe dados pessoais relevantes ao sair da conta em dispositivos compartilhados. Mantenha trabalhos importantes em um servidor ou ofereça exportação, pois usuários podem limpar os dados do site e sessões privadas os descartam.
Cookies são diferentes: requisições correspondentes os enviam ao servidor, e cookies HttpOnly não podem ser lidos por scripts da página. Eles são pequenos, cerca de 4 KB cada. O armazenamento web permanece no navegador e pode ser lido por scripts. IndexedDB é adequado para volumes maiores de dados estruturados por meio de uma API assíncrona.
Principais conclusões
- Valide os dados analisados e recorra a valores padrão quando estiverem ausentes ou danificados.
- A validade do cache depende de uma marca de tempo e de um limite de idade definido pela aplicação.
- O evento
storagechega a outras abas da mesma origem, não à aba que gravou. - Mantenha segredos e dados insubstituíveis fora do armazenamento web.
5Usar recursos de localização e da área de transferência
APIs do navegador conectam uma página a recursos como localização e área de transferência. Sua disponibilidade depende do navegador, do contexto de segurança da página e das escolhas do usuário. Você detectará um recurso antes de chamá-lo, pedirá permissão em um momento útil e tratará o sucesso ou a recusa. Uma interação completa inclui uma resposta visível e outra maneira de concluir a tarefa, como digitar uma cidade ou copiar texto selecionado com o teclado.
5.1 Solicitar uma localização com uma alternativa
A Geolocalização é uma API do navegador: um recurso fornecido pelo navegador, separado da linguagem JavaScript. Como outros recursos do dispositivo, ela pode estar indisponível ou ter seu uso recusado. Uma página de previsão do tempo deve continuar funcionando quando um leitor optar por digitar uma cidade.
Verificar o recurso e o contexto
Detecte o próprio recurso com "geolocation" in navigator. Verificar o nome de um navegador é menos confiável: versões e configurações alteram o que está disponível. A Geolocalização precisa de um contexto seguro, normalmente HTTPS; http://localhost também atende ao requisito para desenvolvimento. window.isSecureContext informa se a página atual atende ao requisito. HTTP simples no endereço de rede de outro dispositivo não é o mesmo que localhost.
Explique por que a localização é útil e solicite-a quando o leitor clicar em “Usar minha localização”. O navegador gerencia a solicitação de permissão. Uma pessoa pode permitir ou bloquear o acesso, e uma recusa anterior pode fazer uma chamada posterior falhar sem outra solicitação. O usuário altera essa decisão nas configurações do site.
Ler o resultado da função de retorno
navigator.geolocation.getCurrentPosition(success, error, options) usa funções de retorno. Em caso de sucesso, position.coords contém latitude e longitude em graus decimais e accuracy em metros. A precisão é um raio estimado de incerteza, não uma precisão decimal adicional. Em caso de falha, o código 1 significa permissão negada, 2 significa posição indisponível e 3 significa limite de tempo excedido.
As opções controlam a tentativa:
enableHighAccuracy: solicita maior precisão; padrãofalse.timeout: limite de espera em milissegundos; padrãoInfinity.maximumAge: idade máxima de uma posição em cache aceitável; padrão0.
Use um limite de tempo finito para que a página tenha uma forma de sair da espera. watchPosition observa atualizações ao longo do tempo e retorna um ID; passe esse ID para clearWatch quando o acompanhamento precisar parar.
Envolver funções de retorno ao usar await
function getPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, options);
});
}
async function useLocation() {
if (!("geolocation" in navigator)) {
showCityInput();
return;
}
try {
const { coords } = await getPosition({ timeout: 10000 });
const url = new URL("https://api.example.com/weather");
url.searchParams.set("lat", coords.latitude.toFixed(2));
url.searchParams.set("lon", coords.longitude.toFixed(2));
await loadWeather(url);
} catch {
showCityInput();
}
}
Aqui, showCityInput exibe o controle de entrada manual e loadWeather solicita e renderiza a previsão do tempo. Conecte useLocation ao botão de localização. O bloco catch cobre a falha de localização e a requisição de previsão do tempo; em ambos os casos, a entrada manual continua disponível.
Solicitar apenas a precisão útil
Uma posição com latitude 52.3676, longitude 4.9041 e precisão 35 tem um raio estimado de cerca de 35 m. Arredondar para 52.37 e 4.90 reduz a precisão enviada ao serviço de previsão do tempo. Um intervalo de latitude de 0,01° equivale a cerca de 1,1 km; a distância entre longitudes varia com a latitude. Essa precisão regional é adequada para uma previsão sem compartilhar as coordenadas mais detalhadas.
Onde a API de Permissões estiver disponível, navigator.permissions.query({ name: "geolocation" }) informa "granted", "denied" ou "prompt". Detecte e trate essa API também. Seu estado ajuda a adaptar a interface, mas não substitui o tratamento de erros da chamada de localização.
Principais conclusões
- Detecte a Geolocalização e use um contexto seguro.
- Solicite a localização após uma ação clara do usuário, com uma finalidade informada.
- Latitude e longitude usam graus; a precisão usa metros.
- Defina um limite de tempo finito e ofereça entrada manual em caso de falha.
- Envie apenas a precisão de localização necessária ao recurso.
- O estado da permissão não garante uma posição utilizável.
5.2 Copiar texto e aprender outra API do navegador
A API da área de transferência permite que uma página copie texto sem pedir ao leitor que o selecione primeiro. Assim como a Geolocalização, ela precisa de verificações de disponibilidade, uma ação apropriada do usuário, tratamento de erros e uma alternativa.
Copiar durante o clique
navigator.clipboard.writeText(text) retorna uma promessa. Aguarde-a antes de informar sucesso. Um contexto seguro é obrigatório, e uma operação negada pode ser rejeitada com NotAllowedError. Chame-a diretamente de um tratador de clique: Firefox e Safari exigem uma interação recente do usuário, enquanto os requisitos do Chromium também podem depender da permissão de gravação na área de transferência.
copyButton.addEventListener("click", async () => {
try {
if (!navigator.clipboard?.writeText) {
throw new Error("Copy unavailable");
}
await navigator.clipboard.writeText(codeField.value);
copyButton.textContent = "Copied!";
} catch {
codeField.focus();
codeField.select();
copyButton.textContent = "Copy selected text: Ctrl+C / Cmd+C";
}
setTimeout(() => {
copyButton.textContent = "Copy";
}, 2000);
});
codeField é um campo de texto ou textarea e copyButton é o botão da página. Se a cópia falhar, selecionar o texto oferece uma opção pelo teclado: Ctrl+C em muitos sistemas ou Cmd+C no macOS. O texto do botão volta a ser “Copy” após 2000 ms. Nunca mostre “Copied!” antes de a promessa ser cumprida.
A leitura usa navigator.clipboard.readText() e tem controles mais rigorosos porque uma área de transferência pode conter material privado de outras aplicações. Um navegador pode exigir permissão ou apresentar uma solicitação de colagem. A permissão para gravar não estabelece permissão para ler.
Tratar a conectividade como um indício
navigator.onLine e os eventos online e offline da janela ajudam a mostrar uma faixa de conexão. Eles não estabelecem se sua API está acessível. Um dispositivo pode ter conexão de rede enquanto o servidor da API está fora do ar ou inacessível.
window.addEventListener("offline", () => {
status.textContent = "You are offline.";
});
Continue tratando erros em torno de fetch mesmo quando navigator.onLine for verdadeiro. Use uma região dinâmica apropriada para a mensagem de status.
Ler uma busca compartilhável
A API URL lê a cadeia de consulta da própria página, além de construir URLs de APIs. Em https://books.example.org/search?q=dune, new URL(location.href).searchParams.get("q") retorna "dune". Leia esse valor ao carregar para restaurar uma busca de um link compartilhado. Um parâmetro ausente retorna null, então decida o que a tela inicial deve mostrar nesse caso.
Usar um método de aprendizado
Para outra API do navegador, leia sua sintaxe, regras de contexto seguro e permissão, tabela de compatibilidade e status Baseline na MDN. Depois, detecte o recurso, chame-o a partir de uma ação do usuário quando necessário, trate sua promessa ou funções de retorno e ofereça uma alternativa quando ele estiver ausente ou a permissão for negada.
A API de Notificações exibe notificações do sistema após a permissão; a API de Compartilhamento Web abre um menu de compartilhamento do dispositivo onde há suporte; Canvas desenha gráficos; APIs de mídia controlam áudio e vídeo. Uma API de mapas de terceiros pode adicionar uma biblioteca e uma chave do provedor. Suas credenciais seguem as mesmas regras de chaves secretas de qualquer outro serviço. Testar um navegador em localhost não comprova que outro dispositivo ou navegador tenha o mesmo suporte e contexto.
Principais conclusões
- Aguarde
writeTextantes de informar que a cópia foi bem-sucedida. - Mantenha uma alternativa de cópia pelo teclado quando o acesso à área de transferência falhar.
- A leitura da área de transferência tem regras de permissão separadas e mais rigorosas.
- O estado online não comprova que a API esteja acessível.
- Use parâmetros de URL para restaurar uma busca compartilhável.
- Verifique a compatibilidade, detecte recursos e trate recusas para cada API do navegador.
Exercícios resolvidos de Fetch e APIs do navegador
1Construir e atualizar uma lista de leitura
14 passos
- 1IntroduçãoAcompanhar uma troca
Uma página de lista de leitura precisa carregar livros e adicionar uma nota sobre um deles. A página é o cliente; a API é o servidor. Cada troca tem uma requisição que descreve a ação e uma resposta que descreve seu resultado.
Primeiro, leremos a troca, depois conectaremos as duas etapas assíncronas do carregamento de JSON e, por fim, enviaremos uma alteração. A resposta do servidor determina o que a página pode mostrar com segurança em seguida.
- 2ExemploLer o recurso e os filtros
A página faz a requisição
GET https://api.example.com/books?author=Le%20Guin&limit=5.GETsolicita a leitura./booksidentifica o recurso. A consulta filtra por autor e limita a quantidade de resultados.%20representa o espaço em “Le Guin”. A documentação da API determina esses nomes de parâmetros; a página não pode escolher outro nome e esperar que o serviço o entenda. - 3Ideia-chaveSeparar status de conexão
Uma resposta pode informar
200 OKcom um livro ou404 Not Foundcom um erro. Ambos comprovam que um servidor respondeu. Uma falha de conexão não fornece um status HTTP à página.Inspecione a aba Network para ver a URL completa, o método, o status, os cabeçalhos e o corpo. Se a API retornou o JSON esperado, o próximo lugar a inspecionar é o código que o lê ou exibe.
- 4DesafioEscolher um método para uma alteração
Uma nota já existe. A página deve alterar apenas seu campo
done, preservando seu texto. Qual método HTTP é adequado para essa operação e por queGETestaria errado?---reveal---
Use
PATCHpara a atualização parcial.GETé um método seguro de leitura e não deve ser usado para solicitar uma alteração de dados.PUTdescreveria uma substituição completa e poderia redefinir campos omitidos do corpo. - 5ExplicaçãoAguardar a resposta
Comece com
const response = await fetch(url). Isso aguarda a chegada dos cabeçalhos da resposta e fornece umResponse, não os dados analisados dos livros.A resposta ainda pode ser um erro HTTP.
fetché cumprida para um404porque existe uma resposta. Verifiqueresponse.okantes de tratar a operação como bem-sucedida; ele é verdadeiro para códigos de status de200a299. - 6ExemploVerificar e ler o corpo
Continue dentro da função assíncrona:
if (!response.ok) { throw new Error(`HTTP error ${response.status}`); } const data = await response.json();A segunda espera lê e analisa o corpo. Agora
dataé um valor JavaScript. Umtry/catchexterno pode tratar tanto o erro de status lançado aqui quanto falhas na busca ou na análise do corpo. - 7ExemploEncontrar o vetor aninhado
Suponha que o corpo seja
{"results":[{"title":"Dune"}],"total":1}.A primeira etapa,
data.results, acessa o vetor.[0]acessa seu primeiro objeto..titlefornece"Dune". Uma função de renderização deve receberdata.results, não o objeto externo inteiro. A prévia da resposta na aba Network é útil quando a estrutura da API difere do que a página esperava. - 8DesafioDiagnosticar o valor ausente
O código usa
const data = response.json()e depois tenta acessardata.results[0]. O corpo é realmente um JSON válido com um vetorresults. O que está faltando?---reveal---
Aguarde o corpo:
const data = await response.json(). Sem essa espera,dataé uma promessa e não tem uma propriedaderesults. O primeiroawait fetch(...)não aguardou também a análise do JSON. - 9DicaPreservar a pontuação em uma busca
Construa parâmetros de consulta por meio da API URL:
const url = new URL("https://api.example.com/search"); url.searchParams.set("q", "rock & roll");O valor torna-se
rock+%26+roll. O e comercial permanece dentro da expressão de busca em vez de dividir a consulta. Reutilize a resposta analisada após o carregamento: chamar um segundo leitor de corpo na mesma resposta falha porque o corpo foi consumido. - 10ExemploPreparar um envio JSON
Para criar uma nota, serialize os campos e indique seu formato:
const response = await fetch("https://api.example.com/notes", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title: "Read", done: false }), });O método solicita a criação, o cabeçalho declara JSON e o corpo contém texto JSON em vez de um objeto comum.
- 11ConexãoUsar o registro armazenado
O servidor pode retornar
201 Createdcom{"id":31,"title":"Read","done":false}. Adicione esse registro retornado ao estado da página. Seu ID permite que uma ação posterior chame/notes/31.Para um formulário com arquivos, passe
FormDataem vez de JSON e deixe o navegador definir seu delimitador multipart. Uma requisiçãoGETnão pode transportar um corpo por meio defetch; campos de busca devem ficar na cadeia de consulta. - 12DesafioTratar um sucesso sem corpo
Excluir uma nota salva retorna
204. O código verificaresponse.ok, depois chamaresponse.json()e mostra um erro. A exclusão necessariamente falhou e o que deve mudar?---reveal---
Não:
204informa uma conclusão bem-sucedida sem corpo. Não analise JSON para esse status e atualize a página após a verificação do status. A falha de análise veio da tentativa de ler conteúdo vazio, não de uma evidência de que a exclusão falhou. - 13DesafioRevisar um fluxo completo de envio
Um botão de salvar pode ser clicado duas vezes enquanto um
POSTestá em andamento. Uma resposta bem-sucedida fornece um novo ID. Cite os dois comportamentos da página que impedem uma duplicação acidental e preservam esse ID.---reveal---
Desabilite o botão durante a requisição e restaure-o em
finally. Em caso de sucesso, atualize a partir do registro retornado, incluindo seu ID. O botão impede cliques repetidos; o resultado do servidor fornece valores que não existiam nos dados enviados. - 14RecapitulaçãoVerificar a troca em cada etapa
Quando uma requisição não se comportar como esperado, inspecione a operação em ordem: a URL e o método documentados, o status real, o leitor de corpo escolhido e a estrutura dos dados entregues à página.
Para uma gravação, verifique também o tipo de conteúdo e o corpo serializado. Um sucesso sem conteúdo não precisa de um leitor JSON. Uma resposta de criação deve fornecer o registro salvo usado para a próxima edição ou exclusão.
2Construir uma página de busca que permanece atualizada
18 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoManter a tela associada à busca
- 2ExemploSubstituir a lista anterior
- 3Ideia-chaveDistinguir zero de dados ausentes
- 4DesafioTratar texto e links externos
- 5ExemploLer a unidade de tempo
- 6ExplicaçãoEscolher o fuso de exibição
- 7ExemploFormatar subunidades monetárias documentadas
- 8DesafioSeparar configuração regional de valor
- 9ExplicaçãoComeçar com uma espera visível
- 10ExemploFinalizar todos os caminhos
- 11DesafioReconhecer uma busca vazia bem-sucedida
- 12DicaAguardar antes de uma nova tentativa por falha temporária
- 13ExemploObservar a ordem de conclusão
- 14ExemploCancelar uma requisição antiga
- 15ConexãoReduzir chamadas durante a digitação
- 16DesafioEscolher sucesso parcial
- 17DesafioProteger toda a interação atual
- 18RecapitulaçãoTestar a interface com respostas imperfeitas
3Diagnosticar uma chamada de API de outra origem
10 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoSeparar duas questões de permissão
- 2ExemploComparar as origens completas
- 3ExplicaçãoLer a permissão do servidor
- 4ExemploAcompanhar primeiro a verificação prévia
- 5DesafioExplicar um sucesso apenas no terminal
- 6ExemploEncontrar a chave exposta
- 7ConexãoMover o limite do segredo
- 8DesafioDistinguir transporte de segredo
- 9DesafioVerificar cookies e respostas legíveis
- 10RecapitulaçãoDiagnosticar o limite que falhou
4Restaurar uma lista salva sem interromper a página
12 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoManter uma cópia local de conveniência
- 2ExplicaçãoEscolher o que deve permanecer
- 3ExemploPreservar um vetor como texto
- 4DesafioRestaurar o tipo pretendido
- 5DicaTratar uma gravação que não cabe
- 6ExemploVerificar mais do que a sintaxe JSON
- 7ExemploAdicionar um horário ao cache
- 8DesafioCalcular qual cache está válido
- 9ConexãoAcompanhar um tema entre abas
- 10Ideia-chaveProteger dados importantes
- 11DesafioRecuperar-se de um formato salvo antigo
- 12RecapitulaçãoTestar uma primeira visita e uma visita de retorno
5Adicionar botões úteis de localização e cópia
13 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoTornar a ação compreensível
- 2ExplicaçãoVerificar o contexto e o recurso
- 3DicaSolicitar quando o recurso for útil
- 4ExemploDefinir uma espera finita
- 5ExemploLer apenas a precisão útil
- 6DesafioRecuperar-se de uma recusa
- 7ExemploGravar durante o clique
- 8Ideia-chaveAguardar antes de informar a cópia
- 9DesafioTratar um sinal de conexão como indício
- 10ConexãoRestaurar uma busca a partir de seu link
- 11DicaVerificar outro recurso do navegador
- 12DesafioRevisar os dois botões juntos
- 13RecapitulaçãoTestar também as escolhas da pessoa
Questões de Fetch e APIs do navegador
Conjunto 1: Depurar requisições, armazenamento e permissões10 Questões de Prática
Questão 1 de 10
PUT /profiles/29 como substituição do perfil. O que a idempotência implica quando a mesma requisição completa é enviada duas vezes?Mostrar respostaOcultar resposta
Questão 2 de 10
Mostrar respostaOcultar resposta
Questão 3 de 10
new Date e mostra janeiro de 1970. Qual conversão deve preceder a formatação da data?Mostrar respostaOcultar resposta
Date do JavaScript conta milissegundos, então multiplique o valor documentado por 1000. Uma configuração regional controla como uma data é escrita e não pode corrigir a unidade de tempo errada. Adicionar um deslocamento de fuso também não corrige uma marca de tempo menor por um fator de 1000.Questão 4 de 10
503 com Retry-After: 12. Qual comportamento comunica o estado e permite a recuperação?Mostrar respostaOcultar resposta
Retry-After: 12 solicita uma espera de doze segundos antes de outra tentativa; tentar novamente de imediato ignora essa instrução. Um 503 é uma falha do serviço, não uma evidência de que o catálogo não contém itens.Questão 5 de 10
Mostrar respostaOcultar resposta
Questão 6 de 10
Mostrar respostaOcultar resposta
Questão 7 de 10
if (localStorage.getItem("compact")). O texto armazenado é "false", mas o modo compacto é ativado. Por quê?Mostrar respostaOcultar resposta
getItem retorna texto, e a cadeia não vazia "false" é avaliada como verdadeira em JavaScript. Ela não volta a ser automaticamente o booleano false. Se o formato armazenado for "true" ou "false", compare o valor explicitamente com "true" ao restaurar a configuração.Questão 8 de 10
Mostrar respostaOcultar resposta
Questão 9 de 10
-12.0464, longitude -77.0428 e precisão 80. O que 80 descreve?Mostrar respostaOcultar resposta
Questão 10 de 10
https://recipes.example.org/search?q=green+tea lê new URL(location.href).searchParams.get("q"). Qual valor ela obtém?Mostrar respostaOcultar resposta
searchParams.get("q") obtém e decodifica o valor do parâmetro de consulta indicado, então o sinal de adição torna-se um espaço em "green tea". Ele não retorna o nome do parâmetro nem a consulta codificada bruta. Um parâmetro ausente retornaria null, mas q está presente nesse endereço.Conjunto 2: Requisições, resultados e recursos do navegador10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
amount: 3785, currency: "USD" como subunidades monetárias inteiras. Qual número deve ser passado ao formatador de moeda?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
403. O que esse status informa à página?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
200 com {"items":[{"name":"Cedar"}]}. Qual atribuição armazena o nome do primeiro item após const response = await fetch(url)?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
body deve receber ao enviar { label: "Read" }?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
{ remaining: 0, owner: null }. Como a página pode exibir a quantidade restante e usar "Unknown" para o nome ausente do responsável?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
https://studio.example.org/edit. Qual é a origem dessa página?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
localStorage.setItem("visits", 8), qual é o valor de localStorage.getItem("visits") + 1?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
1. Qual resposta ao usuário é adequada para essa falha?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 3: Acompanhar os dados pela interface10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
Promise.all?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
fetch retorna um Response com status 502. O código tem um tratador catch, mas nunca verifica response.ok. Por que sua mensagem de erro HTTP pode nunca aparecer?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
204 em caso de sucesso. O que a página deve fazer antes de tentar analisar JSON?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
POST com JSON e Content-Type: application/json. Nenhuma permissão de verificação prévia está em cache. O que o navegador deve verificar antes de enviar esse POST?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
http://localhost, mas seu recurso de localização está ausente quando aberta em um celular por um endereço de rede HTTP. A aplicação também para de funcionar quando usuários de computador negam a localização. Qual projeto resolve as duas falhas?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
navigator.clipboard.writeText(text). Em que momento ele deve mostrar “Copiado!”?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 4: Projetar recursos de API confiáveis10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
429. O que esse status significa?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
<b>, um link javascript: e remaining: 0. A página deve mostrar o título literalmente, permitir apenas links web comuns e preservar a contagem. Qual plano de renderização atende às três necessidades?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
Intl.DateTimeFormat com a configuração regional fixa en-US, mas sem a opção timeZone. Os horários exibidos são diferentes. O que explica a diferença?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
PATCH com JSON entre origens usa credentials: "include". A verificação prévia o permite. A resposta final tem um curinga allow-origin e permite credenciais, então o JavaScript não consegue lê-la. O servidor também supõe que o CORS torna desnecessárias as verificações do usuário. Qual política de resposta e acesso corrige esse projeto?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
.map imediatamente. Alguns usuários têm o JSON válido {"version":1,"items":[]} deixado por código antigo, e outros têm texto danificado. Qual plano de restauração trata os dois casos?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
navigator.onLine === true, mas uma chamada de API é rejeitada. O que a página deve concluir sobre a conectividade e tratar em seguida?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Travou em uma questão sua? Ajuda com Tarefas
Termos-Chave
A
Adiamento até cessarem os eventos
Alternativa de contingência
API da área de transferência
API web
Armazenamento web
Ativação pelo usuário
Atributo HttpOnly
Á
Área de armazenamento localStorage
Área de armazenamento sessionStorage
B
Baseline
C
Cabeçalho
Content-Type informa ao programa destinatário que o corpo que o acompanha contém JSON.Cabeçalho Retry-After
Retry-After de 15 pede que a página aguarde quinze segundos antes de outra requisição.Cache
Chave de API
Coalescência nula
?? apenas quando o valor à sua esquerda é null ou undefined, preservando zeros válidos.Codificação de URL
Código de status
201 informa à página que o servidor criou um recurso em resposta à requisição.Coleção FormData
Compartilhamento de recursos entre origens
Condição de corrida
Configuração regional
en-US escreve uma data de forma diferente de en-GB, mesmo quando ambas formatam o mesmo instante.Conteúdo misto
Contexto seguro
Controlador de cancelamento
Corpo da requisição
Corpo da resposta
Cota de armazenamento
D
Delimitador multipart
Detecção de recursos
"geolocation" in navigator determina se a página pode oferecer a localização do dispositivo.E
Encadeamento opcional
?. é null ou undefined, retornando undefined.book.author?.name trate um livro cujo objeto de autor está ausente da resposta.Erro de análise sintática
204 vazio causa um erro de análise sintática de JSON, embora o servidor tenha concluído a operação com sucesso.Espera exponencial entre tentativas
Estado de carregamento
Estado vazio
Evento storage
Expiração
F
Formatador Intl.NumberFormat
Intl.NumberFormat para cada preço em vez de reconstruir uma cadeia monetária para cada item.Fuso horário
G
Geolocalização
I
Idempotência
IndexedDB
Injeção de scripts entre sites
textContent para títulos de APIs elimina a interpretação como HTML que pode permitir a injeção de scripts entre sites.J
JSON
results antes de construir itens de lista.L
Limite de requisições por período
M
Marca de tempo Unix
Método Promise.all
Método Promise.allSettled
O
Objeto Response
200, mas a página ainda aguarda json() para obter os dados do livro.Operação síncrona
Origem
P
Paginação
Parâmetro de consulta
?, usado por um ponto de acesso para entradas como buscas ou limites de página.limit=12 pede ao ponto de acesso de busca que retorne no máximo doze resultados.Permissão
Política de mesma origem
Ponto de acesso da API
POST para criar uma nota e retorna o identificador do novo registro.Precisão da localização
Propriedade textContent
textContent exibe seus sinais de menor e maior literalmente em vez de criar um elemento HTML.R
Região dinâmica
role="status" anuncia “Carregando…” e a mensagem posterior do resultado da busca.Renderização
Requisição de verificação prévia
Requisição HTTP
/books e inclui um parâmetro de consulta que limita a quantidade de resultados.Resposta HTTP
404 e explica em seu corpo que o livro solicitado não foi encontrado.Resposta opaca
S
Serialização
JSON.stringify preserva os campos de uma nota quando são enviados como corpo de requisição JSON.Sinal de cancelamento
AbortSignal.timeout(4000) limita uma requisição a quatro segundos de tempo ativo.Subunidade monetária
4680 representa 46.80 dólares.T
Tempo Universal Coordenado
Z no final de uma data e hora ISO.Token de acesso
Sobre esta aula
Crie seus próprios Materiais de Estudo
Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.