Às vezes, é útil enviar alguns dados de uma página da Web para um servidor da Web sem precisar esperar por uma resposta. Por exemplo, talvez queiramos enviar dados de análise ou diagnóstico antes que o usuário saia de uma página.
Normalmente, o envio de dados antes da saída envolvia a detecção do evento unload
,
porque o envio da solicitação antes disso resultaria em dados incompletos.
Por exemplo, poderíamos ter perdido um clique que aconteceu pouco antes da saída.
A ressalva era que as solicitações enviadas no gerenciador de despejo precisavam
ser síncronas, porque a maioria dos navegadores geralmente ignora XMLHttpRequests assíncronos feitos em um gerenciador de despejo.
Essa abordagem retarda a navegação, já que o usuário precisa
esperar a solicitação voltar antes que uma nova página seja renderizada.
A API Beacon resolve esse problema, permitindo que você envie assíncronamente solicitações HTTP com pequenos payloads de dados de um navegador para um servidor da Web, sem atrasar outros códigos no evento de remoção da página ou afetar o desempenho da próxima navegação de página.
O método navigator.sendBeacon()
enfileira os dados a serem
transmitidos pelo navegador o mais rápido possível,
mas não retarda a navegação.
Ele retorna true
se o navegador conseguir enfileirar
os dados para transferência. Caso contrário, ele retorna false
.
Digamos que temos um endpoint do servidor disponível para receber dados de beacon da nossa página neste endereço:
https://putsreq.herokuapp.com/Dt7t2QzUkG18aDTMMcop
Se adicionarmos um método sendBeacon()
no manipulador de eventos pagehide
,
o endpoint vai receber os dados quando o usuário sair da página:
Se você inspecionar a guia "Rede" no Chrome DevTools com a caixa de seleção preserve logs marcada, vai aparecer uma solicitação HTTP POST para o endpoint acima sendo enviada quando você sair da página.
Também é possível acessar a página de inspeção do PutsReq para conferir se os dados do beacon foram recebidos.
Há também um elemento personalizado do Polymer que permite enviar dados de beacons: <beacon-send>
. Confira em ebidel.github.io/beacon-send.