Tous les articles

ReportingObserver, capter les deprecations et violations CSP en JavaScript

CentralCSP Team ·

Dernière mise à jour:

L'essentiel du Reporting API envoie les rapports du navigateur vers un serveur que vous contrôlez. L'API ReportingObserver fait l'inverse : elle remet ces mêmes rapports à votre propre JavaScript, à l'intérieur de la page, dès qu'ils se déclenchent. Aucun header de réponse, aucun endpoint, aucun backend. Vous construisez un observer, vous lui donnez un callback, et le navigateur commence à vous appeler avec les avertissements de deprecation, les interventions du navigateur et (là où c'est pris en charge) les violations CSP au fil de l'eau. C'est le pendant in-page du reporting par endpoint, et il s'insère directement dans un pipeline d'erreurs front-end que vous exécutez déjà.

Ce qu'il observe

ReportingObserver est un constructeur disponible dans le JavaScript de la page elle-même. Vous le pointez vers les types de rapports qui vous intéressent et il livre à votre callback les rapports correspondants. Il couvre :

  • deprecation, une API utilisée par votre page est vouée à disparaître.
  • intervention, le navigateur a remplacé quelque chose que votre code demandait.
  • les violations CSP, là où le navigateur les expose via cette interface.

Ce sont les mêmes événements que le navigateur regrouperait sinon pour les envoyer en POST à un serveur. La différence, c'est l'endroit où vous les lisez : dans la page, en temps réel, avec l'objet report complet en main. L'observer expose les rapports de deprecation, d'intervention et de violation CSP ; les rapports de crash ne l'atteignent jamais et vont uniquement vers un endpoint serveur. Des trois qu'il expose, la livraison des violations CSP est la moins constante d'un navigateur à l'autre, confirmez-la donc dans vos navigateurs cibles avant d'en dépendre.

Mettez-en un en place

Vous créez l'observer avec un callback et un objet d'options. Le callback reçoit une liste de rapports et l'observer lui-même. Les deux options qui comptent sont types, les types de rapports à surveiller, et buffered, qui rejoue les rapports déclenchés avant l'existence de votre observer pour que vous ne ratiez pas les premiers pendant le chargement de la page.

reporting-observer.ts
const  = new (
  (, ) => {
    for (const  of ) {
      // report.type is "deprecation", "intervention", or "csp-violation"
      // report.body holds the type-specific fields
      ({
        : .,
        : .,
        : .,
      });
    }
  },
  { : ["deprecation", "intervention"], : true }
);

.();

Appelez observe() pour démarrer. Le flag buffered: true est ce qui rend la chose fiable : une deprecation peut se déclencher alors que votre bundle est encore en cours d'analyse, et sans buffering vous ne la verriez jamais. Avec lui, ces premiers rapports sont rejoués dans votre premier callback.

Intégrez-le à un pipeline d'erreurs front-end

Si vous capturez déjà les erreurs JavaScript et les rejets non gérés dans le navigateur pour les envoyer à un service de logs, ReportingObserver est une source de plus pour ce même pipeline. Traitez chaque rapport comme un événement d'erreur : taguez-le avec le type, joignez l'emplacement source issu de report.body, et envoyez-le par le canal que vous avez déjà.

error-pipeline.js
function sendToErrorPipeline(entry) {
  // reuse your existing client logger / beacon
  navigator.sendBeacon("/client-logs", JSON.stringify(entry));
}

window.addEventListener("error", (e) =>
  sendToErrorPipeline({ type: "js-error", message: e.message })
);

new ReportingObserver(
  (reports) => reports.forEach((r) =>
    sendToErrorPipeline({ type: r.type, body: r.body })
  ),
  { types: ["deprecation", "intervention"], buffered: true }
).observe();

Utiliser sendBeacon évite que le rapport soit perdu quand l'utilisateur quitte la page, la même raison pour laquelle le Reporting API livre hors bande. Désormais une deprecation apparaît dans le même dashboard qu'une exception levée, avec le fichier source et la ligne qui l'ont déclenchée.

Il complète le reporting par endpoint, il ne le remplace pas

ReportingObserver et le reporting par endpoint répondent à des questions différentes, c'est pourquoi la plupart des équipes veulent les deux.

  • L'observer ne s'exécute que tant que votre page est vivante et ne voit que ce que cette session produit. Il est idéal pour la télémétrie front-end en temps réel et pour router les rapports vers un outillage que vous possédez déjà.
  • Le reporting par endpoint, déclaré avec le header Reporting-Endpoints, continue de fonctionner une fois la page partie, agrège sur l'ensemble de votre trafic, et capte des types de rapports que l'observer ne voit pas, comme les rapports de crash. C'est la vue de référence, côté serveur.

Servez-vous de l'observer pour faire remonter vite les problèmes dans votre propre pile front-end, et du reporting par endpoint comme enregistrement durable. Mettez en place le côté endpoint dans comment configurer le Reporting API, et lisez le catalogue complet des types de rapports sur la référence des rapports. Le fonctionnement de l'observer lui-même est sur la page de concept ReportingObserver.

Envoyez les deux vues au même endroit

L'observer vous donne les rapports dans le navigateur ; l'endpoint vous donne les rapports issus du trafic réel. CentralCSP ingère tous les types de rapports du navigateur côté endpoint, donc votre ReportingObserver et votre configuration Reporting-Endpoints peuvent alimenter la même vue de reporting, avec les deprecations, les interventions et les violations CSP regroupées et suivies dans le temps au lieu d'être éparpillées entre une console et un fichier de log. Vous obtenez le signal front-end en temps réel et l'enregistrement durable, multi-trafic, sans construire deux pipelines.

L'explorateur de rapports, avec le sélecteur de type ouvert au-dessus du tableau

Étapes suivantes

Collectez tous les rapports du navigateur au même endroit.

Sources

Articles liés