Monitorar seu aplicativo da Web com a API Reporting

Use a API Reporting para monitorar violações de segurança, chamadas de API descontinuadas e muito mais.

Maud Nalpas
Maud Nalpas

Alguns erros só ocorrem na produção. Elas não são exibidas localmente ou durante o desenvolvimento, porque usuários reais, redes reais e dispositivos reais mudam o jogo. A API Reporting ajuda a detectar alguns desses erros, como violações de segurança ou chamadas de API descontinuadas e em breve no seu site, e os transmite para um endpoint especificado por você.

Ele permite declarar o que você quer monitorar usando cabeçalhos HTTP e é operado pelo navegador.

Ao configurar a API Reporting, você tem a tranquilidade de saber que, quando os usuários encontram esses tipos de erros, pode corrigi-los.

Nesta postagem, explicamos o que essa API pode fazer e como usá-la. Vamos lá!

Demonstração e código

Confira a API Reporting em ação a partir do Chrome 96 e versões mais recentes (Chrome Beta ou Canary, a partir de outubro de 2021).

Visão geral

Diagrama com o resumo das etapas abaixo, desde a geração do relatório até o acesso ao relatório pelo desenvolvedor
Como os relatórios são gerados e enviados.

Vamos supor que o site site.example tenha uma Política de Segurança de Conteúdo e uma Política de Documentos. Não sabe o que elas fazem? Tudo bem, você ainda poderá entender este exemplo.

Você decide monitorar seu site para saber quando essas políticas são violadas, mas também porque quer ficar de olho nas APIs descontinuadas ou que serão desativadas em breve pela sua base de código.

Para isso, configure um cabeçalho Reporting-Endpoints e mapeie esses nomes de endpoint usando a diretiva report-to nas suas políticas quando necessário.

Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"
# Content-Security-Policy violations and Document-Policy violations
# will be sent to main-endpoint
Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0; report-to=main-endpoint;
# Deprecation reports don't need an explicit endpoint because
# these reports are always sent to the `default` endpoint

Algo imprevisto acontece, e essas políticas são violadas para alguns dos usuários.

Exemplos de violação

index.html

<script src="script.js"></script>
<!-- CSP VIOLATION: Try to load a script that's forbidden as per the Content-Security-Policy -->
<script src="https://example.com/script.js"></script>

script.js, carregado por index.html

// DOCUMENT-POLICY VIOLATION: Attempt to use document.write despite the document policy
try {
  document.write('<h1>hi</h1>');
} catch (e) {
  console.log(e);
}
// DEPRECATION: Call a deprecated API
const webkitStorageInfo = window.webkitStorageInfo;

O navegador gera um relatório de violação da CSP, um relatório de violação da política de documentos e um relatório de descontinuação que capturam esses problemas.

Com um pequeno atraso de até um minuto, o navegador envia os relatórios ao endpoint que foi configurado para esse tipo de violação. Os relatórios são enviados fora de banda pelo próprio navegador (não pelo servidor nem pelo site).

Os endpoints recebem esses relatórios.

Agora é possível acessar os relatórios sobre esses endpoints e monitorar o que deu errado. Você já pode começar a resolver o problema que está afetando seus usuários.

Exemplo de relatório

{
  "age": 2,
  "body": {
    "blockedURL": "https://site2.example/script.js",
    "disposition": "enforce",
    "documentURL": "https://site.example",
    "effectiveDirective": "script-src-elem",
    "originalPolicy": "script-src 'self'; object-src 'none'; report-to main-endpoint;",
    "referrer": "https://site.example",
    "sample": "",
    "statusCode": 200
  },
  "type": "csp-violation",
  "url": "https://site.example",
  "user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
}

Casos de uso e tipos de relatórios

A API Reporting pode ser configurada para ajudar você a monitorar vários tipos de avisos ou problemas interessantes que acontecem no site:

Tipo de relatório Exemplo de uma situação em que um relatório seria gerado
Violação de CSP (somente nível 3) Você configurou um Content-Security-Policy (CSP) em uma das suas páginas, mas a página está tentando carregar um script que não é permitido pela CSP.
Violação da COOP Você definiu um Cross-Origin-Opener-Policy em uma página, mas uma janela de origem cruzada está tentando interagir diretamente com o documento.
Violação da COEP Você definiu um Cross-Origin-Embedder-Policy em uma página, mas o documento inclui um iframe de origem cruzada que não aceitou ser carregado por documentos de origem cruzada.
Violação da política de documentos A página tem uma política de documento que impede o uso de document.write, mas um script tenta chamar document.write.
Violação da política de permissões A página tem uma política de permissões que impede o uso do microfone e um script que solicita entrada de áudio.
Aviso de descontinuação A página usa uma API que foi descontinuada ou será descontinuada. Ela a chama diretamente ou por um script de terceiros de nível superior.
Intervenção A página está tentando fazer algo que o navegador decide não respeitar por motivos de segurança, desempenho ou experiência do usuário. Exemplo no Chrome: a página usa document.write em redes lentas ou chama navigator.vibrate em um frame de origem cruzada com que o usuário ainda não interagiu.
Acidente O navegador falha enquanto seu site está aberto.

Relatórios

Como são os relatórios?

O navegador envia relatórios para o endpoint que você configurou. Ele envia solicitações parecidas com estas:

POST
Content-Type: application/reports+json

O payload dessas solicitações é uma lista de relatórios.

Exemplo de lista de relatórios

[
  {
    "age": 420,
    "body": {
      "columnNumber": 12,
      "disposition": "enforce",
      "lineNumber": 11,
      "message": "Document policy violation: document-write is not allowed in this document.",
      "policyId": "document-write",
      "sourceFile": "https://site.example/script.js"
    },
    "type": "document-policy-violation",
    "url": "https://site.example/",
    "user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
  },
  {
    "age": 510,
    "body": {
      "blockedURL": "https://site.example/img.jpg",
      "destination": "image",
      "disposition": "enforce",
      "type": "corp"
    },
    "type": "coep",
    "url": "https://dummy.example/",
    "user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
  }
]

Veja os dados que você pode encontrar em cada um desses relatórios:

Campo Descrição
age O número de milissegundos entre o carimbo de data/hora do relatório e o horário atual.
body Os dados do relatório, serializados em uma string JSON. Os campos contidos no body de um relatório são determinados pela type. ⚠️ Relatórios de diferentes tipos têm corpos diferentes. Para ver o corpo exato de cada tipo de relatório, confira o endpoint de relatórios de demonstração e siga as instruções para gerar exemplos de relatório.
type Um tipo de relatório, por exemplo, csp-violation ou coep.
url O endereço do documento ou worker a partir do qual o relatório foi gerado. Dados confidenciais, como nome de usuário, senha e fragmento, são removidos desse URL.
user_agent O cabeçalho User-Agent da solicitação a partir da qual o relatório foi gerado.

Relatórios credenciados

Os endpoints de relatórios que têm a mesma origem que a página que gera o relatório recebem as credenciais (cookies) nas solicitações que contêm os relatórios.

As credenciais podem dar mais contexto útil sobre o relatório, por exemplo, se a conta de um determinado usuário aciona erros de maneira consistente ou se uma determinada sequência de ações realizadas em outras páginas está acionando um relatório nessa página.

Quando e como o navegador envia relatórios?

Os relatórios são enviados fora de banda do site: o navegador controla quando são enviados para os endpoints configurados. Também não é possível controlar quando o navegador envia relatórios. Ele captura, coloca em fila e envia os relatórios automaticamente em um momento adequado.

Isso significa que há pouca ou nenhuma preocupação com o desempenho ao usar a API Reporting.

Os relatórios são enviados com um atraso (de até um minuto) para aumentar as chances de serem enviados em lotes. Isso economiza largura de banda para respeitar a conexão de rede do usuário, o que é especialmente importante em dispositivos móveis. O navegador também poderá atrasar a entrega se estiver ocupado processando um trabalho de maior prioridade ou se o usuário estiver em uma rede lenta e/ou congestionada no momento.

Problemas próprios e de terceiros

Os relatórios gerados devido a violações ou descontinuações acontecendo na sua página serão enviados para os endpoints que você configurou. Isso inclui violações cometidas por scripts de terceiros em execução na sua página.

As violações ou descontinuações que ocorreram em um iframe de origem cruzada incorporado na sua página não serão informadas aos endpoints. Pelo menos não por padrão. Um iframe pode configurar os próprios relatórios e gerar relatórios para o serviço de relatórios do seu site, ou seja, do próprio serviço de relatórios. No entanto, isso depende do site enquadrado. A maioria dos relatórios só é gerada quando a política de uma página é violada. Além disso, as políticas dela e do iframe são diferentes.

Exemplo com descontinuações

Se o cabeçalho Reporting-Endpoints estiver configurado na sua página: a API obsoleta chamada por scripts de terceiros em execução na sua página será informada para o endpoint. Uma API suspensa chamada por um iframe incorporado à página não será informada ao endpoint. Um relatório de descontinuação só será gerado se o servidor de iframe tiver configurado os endpoints de relatório. Esse relatório será enviado para qualquer endpoint que o servidor do iframe tiver configurado.
Se o cabeçalho Reporting-Endpoints estiver configurado na sua página: a API descontinuada chamada por scripts de terceiros em execução na sua página será informada para o endpoint. Uma API suspensa chamada por um iframe incorporado à página não será informada ao endpoint. Um relatório de descontinuação só será gerado se o servidor de iframe tiver configurado os endpoints de relatório. Esse relatório será enviado para qualquer endpoint que o servidor do iframe tiver configurado.

Suporte ao navegador

A tabela abaixo resume o suporte do navegador à API Reporting v1, ou seja, com o cabeçalho Reporting-Endpoints. O suporte do navegador para a API Reporting v0 (cabeçalho Report-To) é o mesmo, exceto por um tipo de relatório: o Network Error Logging não é compatível com a nova API Reporting. Para mais detalhes, leia o Guia de migração.

Tipo de relatório Chrome Chrome para iOS Safari Firefox Borda
Violação da CSP (somente nível 3)* ✔ Sim ✔ Sim ✔ Sim ✘ Não ✔ Sim
Geração de registros de erros de rede ✘ Não ✘ Não ✘ Não ✘ Não ✘ Não
Violação de COOP/COEP ✔ Sim ✘ Não ✔ Sim ✘ Não ✔ Sim
Todos os outros tipos: violação da política de documentos, descontinuação, intervenção, falha ✔ Sim ✘ Não ✘ Não ✘ Não ✔ Sim

Esta tabela apenas resume o suporte para report-to com o novo cabeçalho Reporting-Endpoints. Leia as Dicas de migração de relatórios da CSP se quiser migrar para o Reporting-Endpoints.

Como usar a API Reporting

Decida para onde os relatórios devem ser enviados

Você tem duas opções:

  • Envie relatórios para um serviço de coletor de relatórios atual.
  • Envie relatórios para um coletor que você criou e opera por conta própria.

Opção 1: usar um serviço de coletor de relatórios atual

Alguns exemplos de serviços de coletor de relatórios são:

Se você souber de outras soluções, abra um problema para nos informar e atualizaremos esta postagem.

Além do preço, considere os seguintes pontos ao selecionar um coletor de relatórios: 🧐

  • Este coletor oferece suporte a todos os tipos de relatório? Por exemplo, nem todas as soluções de endpoint de relatórios são compatíveis com relatórios COOP/COEP.
  • Você se sente confortável em compartilhar qualquer um dos URLs do seu aplicativo com um coletor de relatórios terceirizado? Mesmo que o navegador remova informações sensíveis desses URLs, pode haver vazamento. Se isso parecer muito arriscado para seu aplicativo, opere seu próprio endpoint de relatórios.

Opção 2: criar e operar seu próprio coletor de relatórios

Criar seu próprio servidor que recebe relatórios não é tão simples. Para começar, você pode bifurcar nosso modelo leve. Ele é criado com o Express e pode receber e exibir relatórios.

  1. Acesse o coletor de relatórios padrão.

  2. Clique em Remixar para editar para tornar o projeto editável.

  3. Agora você tem seu clone! Você pode personalizá-lo de acordo com suas próprias finalidades.

Se você não estiver usando o padrão e estiver criando seu próprio servidor do zero:

  • Verifique se há solicitações POST com um Content-Type de application/reports+json para reconhecer solicitações de relatórios enviadas pelo navegador para seu endpoint.
  • Se o endpoint estiver em uma origem diferente do seu site, verifique se ele oferece suporte às solicitações de simulação do CORS.

Opção 3: combinar as opções 1 e 2

É possível permitir que um provedor específico cuide de alguns tipos de relatórios, mas tenha uma solução interna para outros.

Nesse caso, defina vários endpoints da seguinte maneira:

Reporting-Endpoints: endpoint-1="https://reports-collector.example", endpoint-2="https://my-custom-endpoint.example"

Configurar o cabeçalho Reporting-Endpoints

Defina um cabeçalho de resposta Reporting-Endpoints. O valor precisa ser um ou uma série de pares de chave-valor separados por vírgulas:

Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"

Se você estiver migrando da API Reporting legada para a nova API Reporting, convém definir ambos como Reporting-Endpoints e Report-To. Veja detalhes no Guia de migração. Se você estiver usando apenas a diretiva report-uri para denunciar violações de Content-Security-Policy, verifique as etapas de migração para os relatórios da CSP.

Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"
Report-To: ...

Chaves (nomes de endpoint)

Cada chave pode ser um nome de sua escolha, como main-endpoint ou endpoint-1. É possível definir endpoints nomeados diferentes para tipos de relatório distintos, por exemplo, my-coop-endpoint e my-csp-endpoint. Com isso, é possível rotear relatórios para diferentes endpoints, dependendo do tipo.

Se você quiser receber relatórios de intervenção, descontinuação e/ou falhas, defina um endpoint chamado default.

Se o cabeçalho Reporting-Endpoints não definir um endpoint default, os relatórios desse tipo não serão enviados, embora sejam gerados.

Valores (URLs)

Cada valor é um URL de sua escolha para enviar os relatórios. O URL a ser definido aqui depende do que você decidiu na Etapa 1.

Um URL de endpoint:

Exemplos

Reporting-Endpoints: my-coop-endpoint="https://reports.example/coop", my-csp-endpoint="https://reports.example/csp", default="https://reports.example/default"

Em seguida, é possível usar cada endpoint nomeado na política apropriada ou usar um único endpoint em todas as políticas.

Onde definir o cabeçalho?

Na nova API Reporting, a que abordamos nesta postagem, o escopo dos relatórios é definido como documentos. Isso significa que, para uma determinada origem, documentos diferentes, como site.example/page1 e site.example/page2, podem enviar relatórios para endpoints diferentes.

Para receber relatórios por violações ou descontinuações em qualquer página do seu site, defina o cabeçalho como um middleware em todas as respostas.

Confira um exemplo no Express:

const REPORTING_ENDPOINT_BASE = 'https://report.example';
const REPORTING_ENDPOINT_MAIN = `${REPORTING_ENDPOINT_BASE}/main`;
const REPORTING_ENDPOINT_DEFAULT = `${REPORTING_ENDPOINT_BASE}/default`;

app.use(function (request, response, next) {
  // Set up the Reporting API
  response.set(
    'Reporting-Endpoints',
    `main-endpoint="${REPORTING_ENDPOINT_MAIN}", default="${REPORTING_ENDPOINT_DEFAULT}"`,
  );
  next();
});

Editar suas políticas

Agora que o cabeçalho Reporting-Endpoints está configurado, adicione uma diretiva report-to a cada cabeçalho de política para o qual você quer receber relatórios de violação. O valor de report-to precisa ser um dos endpoints nomeados que você configurou.

É possível usar o endpoint múltiplo para várias políticas ou usar endpoints diferentes nas políticas.

Para cada política, o valor report-to precisa ser um dos endpoints nomeados que você configurou.

O report-to não é necessário para relatórios de descontinuação, intervenção e falha. Esses relatórios não estão vinculados a nenhuma política. Eles são gerados enquanto um endpoint default está configurado e é enviado para esse endpoint default.

Exemplo

# Content-Security-Policy violations and Document-Policy violations
# will be sent to main-endpoint
Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0;report-to=main-endpoint;
# Deprecation reports don't need an explicit endpoint because
# these reports are always sent to the default endpoint

Exemplo de código

Para ver tudo isso em contexto, confira abaixo um exemplo de servidor Node que usa o Express e reúne todas as partes discutidas neste artigo. Ele mostra como configurar a geração de relatórios para vários tipos diferentes e exibe os resultados.

Depurar a configuração de relatórios

Gerar relatórios intencionalmente

Ao configurar a API Reporting, provavelmente será necessário violar suas políticas intencionalmente para verificar se os relatórios foram gerados e enviados conforme o esperado. Para acessar um exemplo de código que viola políticas e realiza outras ações inadequadas que geram relatórios de todos os tipos, confira esta demonstração.

Poupar tempo

Os relatórios podem ser enviados com um atraso de cerca de um minuto, que é um tempo longo durante a depuração. GMS Felizmente, ao depurar no Chrome, você pode usar a flag --short-reporting-delay para receber relatórios assim que eles forem gerados.

Execute este comando no seu terminal para ativar essa sinalização:

YOUR_PATH/TO/EXECUTABLE/Chrome --short-reporting-delay

Usar o DevTools

No Chrome, use o DevTools para conferir os relatórios que foram ou serão enviados.

Desde outubro de 2021, esse recurso é experimental. Para usá-lo, siga estas etapas:

  1. Use o Chrome versão 96 ou mais recente (digite chrome://version no navegador)
  2. Digite ou cole chrome://flags/#enable-experimental-web-platform-features na barra de URL do Chrome.
  3. Clique em Ativado.
  4. Reinicie o navegador.
  5. Abra o Chrome DevTools.
  6. No Chrome DevTools, abra as configurações. Em "Experimentos", clique em Ativar painel da API de relatórios no painel "Aplicativo".
  7. Atualize o DevTools.
  8. Atualize a página. Os relatórios gerados pela página em que o DevTools está aberto serão listados no painel Application do Chrome DevTools, em Reporting API.
Captura de tela do DevTools listando os relatórios
O Chrome DevTools exibe os relatórios gerados na sua página e o status deles.

Status do relatório

A coluna Status mostra se um relatório foi enviado.

Status Descrição
Success O navegador enviou o relatório, e o endpoint respondeu com um código de êxito (200 ou outro código de resposta de êxito 2xx).
Pending O navegador está tentando enviar o relatório.
Queued O relatório foi gerado e o navegador não está tentando enviá-lo no momento. Elas aparecem como Queued em um destes dois casos:
  • O relatório é novo, e o navegador está aguardando para ver se vai chegar mais relatórios antes de tentar enviá-lo.
  • O relatório não é novo. O navegador já tentou enviar esse relatório, mas falhou, e está aguardando para tentar novamente.
MarkedForRemoval Depois de tentar novamente por um tempo (Queued), o navegador parou de tentar enviar o relatório e, em breve, o removerá da lista de relatórios a serem enviados.

Os relatórios são removidos depois de algum tempo, mesmo que não sejam enviados.

Solução de problemas

Os relatórios não são gerados ou não são enviados como esperado para seu endpoint? Confira algumas dicas para resolver isso.

Os relatórios não são gerados.

Os relatórios que aparecem no DevTools foram gerados corretamente. Se o relatório esperado não aparecer nessa lista, faça o seguinte:

  • Verifique a report-to nas suas políticas. Se a configuração estiver incorreta, um relatório não será gerado. Acesse Editar suas políticas para corrigir isso. Uma outra maneira de resolver esse problema é verificar o console do DevTools no Chrome: se um erro aparecer no console referente à violação esperada, isso significa que sua política provavelmente está configurada corretamente.
  • Lembre-se de que somente os relatórios gerados para o documento em que o DevTools está aberto serão mostrados nesta lista. Por exemplo: se o site site1.example incorporar um iframe site2.example que viola uma política e, portanto, gerar um relatório, esse relatório só será exibido no DevTools se você abrir o iframe em uma janela própria e abrir o DevTools nessa janela.

Os relatórios são gerados, mas não são enviados ou não são recebidos

E se você consegue ver um relatório no DevTools, mas o endpoint não o recebe?

  • Use atrasos curtos. Talvez você não consiga ver um relatório porque ele ainda não foi enviado.
  • Verifique a configuração do cabeçalho Reporting-Endpoints. Se houver um problema, um relatório gerado corretamente não será enviado. No DevTools, o status do relatório permanecerá Queued. Nesse caso, ele poderá ir para Pending e voltar rapidamente para Queued quando uma tentativa de entrega for feita. Alguns erros comuns que podem causar isso:

  • O endpoint é usado, mas não configurado. Exemplo:

Codificar com um erro
 Document-Policy: document-write=?0;report-to=endpoint-1;
 Reporting-Endpoints: default="https://reports.example/default"

Os relatórios de violação de políticas de documentos precisam ser enviados para endpoint-1, mas esse nome de endpoint não é configurado em Reporting-Endpoints.

  • O endpoint default está ausente. Alguns tipos de relatório, como os de intervenção e descontinuação, vão ser enviados apenas para o endpoint chamado default. Leia mais em Configurar o cabeçalho Reporting-Endpoints.

  • Procure problemas na sintaxe dos cabeçalhos da política, como aspas ausentes. Mais detalhes.

  • Verifique se o endpoint pode processar as solicitações recebidas.

    • Verifique se o endpoint é compatível com solicitações de simulação do CORS. Caso contrário, ele não poderá receber relatórios.

    • Teste o comportamento do endpoint. Para fazer isso, em vez de gerar relatórios manualmente, é possível emular o navegador enviando às solicitações de endpoint uma aparência com aquilo que o navegador enviaria. Execute o comando a seguir:

    curl --header "Content-Type: application/reports+json" \
      --request POST \
      --data '[{"age":420,"body":{"columnNumber":12,"disposition":"enforce","lineNumber":11,"message":"Document policy violation: document-write is not allowed in this document.","policyId":"document-write","sourceFile":"https://dummy.example/script.js"},"type":"document-policy-violation","url":"https://dummy.example/","user_agent":"xxx"},{"age":510,"body":{"blockedURL":"https://dummy.example/img.jpg","destination":"image","disposition":"enforce","type":"corp"},"type":"coep","url":"https://dummy.example/","user_agent":"xxx"}]' \
      YOUR_ENDPOINT
    

    Seu endpoint precisa responder com um código de sucesso (200 ou outro código de resposta de sucesso 2xx). Caso contrário, há um problema com a configuração dele.

Somente relatório

Os cabeçalhos da política -Report-Only e o Reporting-Endpoints funcionam juntos.

Os endpoints configurados em Reporting-Endpoints e especificados no campo report-to de Content-Security-Policy, Cross-Origin-Embedder-Policy e Cross-Origin-Opener-Policy vão receber relatórios quando essas políticas forem violadas.

Os endpoints configurados em Reporting-Endpoints também podem ser especificados no campo report-to de Content-Security-Policy-Report-Only, Cross-Origin-Embedder-Policy-Report-Only e Cross-Origin-Opener-Policy-Report-Only. Eles também recebem denúncias caso essas políticas sejam violadas.

Embora os relatórios sejam enviados em ambos os casos, os cabeçalhos -Report-Only não aplicam as políticas: nada será corrompido ou bloqueado, mas você receberá relatórios do que teria sido corrompido ou bloqueado.

ReportingObserver

A API JavaScript ReportingObserver pode ajudar a observar os avisos do lado do cliente.

ReportingObserver e o cabeçalho Reporting-Endpoints geram relatórios semelhantes, mas permitem casos de uso um pouco diferentes.

Use ReportingObserver se:

  • Você só quer monitorar descontinuações e/ou intervenções do navegador. O ReportingObserver mostra avisos do lado do cliente, como descontinuações e intervenções do navegador. No entanto, ao contrário do Reporting-Endpoints, ele não captura nenhum outro tipo de relatório, como violações de CSP ou COOP/COEP.
  • Você precisa reagir a essas violações em tempo real. O ReportingObserver possibilita anexar um callback a um evento de violação.
  • Anexe mais informações a um relatório para ajudar na depuração usando o callback personalizado.

Outra diferença é que ReportingObserver é configurado apenas no lado do cliente: é possível usá-lo mesmo que você não tenha controle sobre os cabeçalhos do lado do servidor e não possa definir Reporting-Endpoints.

Leia mais

Imagem principal de Nine Koepfer / @enka80 no Unsplash (links em inglês), editada. Agradecemos a Ian Clelland, Eiji Kitamura e Milica Mihajlija pelas avaliações e sugestões feitas neste artigo.