Skip to content

fix(télémétrie): beacon en text/plain — évite le preflight CORS qui perdait tous les événements - #15

Merged
ploteddie-bit merged 1 commit into
mainfrom
fix/tjs-beacon-type-simple
Sep 19, 2026
Merged

ploteddie-bit merged 1 commit into
mainfrom
fix/tjs-beacon-type-simple

Conversation

@ploteddie-bit

Copy link
Copy Markdown
Owner

Problème

La télémétrie first-party de cborweb.com n'enregistrait aucun événement de navigateur. Le compteur events_raw ne contenait que des lignes émises par curl (tests manuels) — la dernière ligne issue d'un navigateur datait du 10/09.

Deux défauts se cumulaient. Le premier (CORS du collecteur, corrigé séparément et déjà déployé) :

Origin envoyé   : https://cborweb.com
ACAO renvoyé    : https://www.cborweb.com   ← comparaison littérale → preflight refusé

Le second, objet de cette PR, n'était visible qu'avec un vrai navigateur : t.js émet ses lots via navigator.sendBeacon avec un Blob de type application/json. Or application/json n'est pas un type « simple » au sens CORS : un preflight est alors exigé, et Firefox l'exécute puis abandonne le POST.

Piège aggravant : sendBeacon renvoie true (mise en file acceptée) alors que la requête n'aboutit jamais — le repli fetch présent juste en dessous n'est donc jamais atteint.

Correctif

Une ligne : le Blob passe en text/plain, type « simple » qui n'exige aucun preflight.

- new Blob([body], { type: "application/json" })
+ new Blob([body], { type: "text/plain" })

Le format du corps est inchangé (toujours du JSON) et le collecteur ne contrôle pas le Content-Type — il fait json.loads() sur le corps. Aucun changement serveur n'est nécessaire.

Preuves — mesurées depuis la page https://cborweb.com dans Firefox, origine du site

Envoi Preflight POST Insertion en base
sendBeacon + Blob application/json (avant) 204 jamais abouti ❌
sendBeacon + Blob text/plain (après) aucun 200 ✅
fetch + keepalive (repli existant) 204 200 ✅

Trace réseau : la requête application/json reste en completed: false ; celle en text/plain revient en 200 sans requête OPTIONS préalable.

Vérification en base (events_raw, base webmaster sur serveur-dev) :

2026-09-19 02:12:06+00 | test-beacon-textplain-20260919 | #beacon-textplain | Mozilla/5.0 (Windows NT 10.0; Win64; x64) … Firefox

Tests

  • node --check docs/site/t.js → OK
  • Recette navigateur réelle après déploiement : navigation + clic sur le site → ligne attendue dans events_raw avec l'empreinte du navigateur.

Contexte

  • Revue complète du diagnostic : docs/revue-e2e-telemetrie-20260918.html (dépôt agent-webmaster)
  • Branche de correction serveur (collecteur CORS) : déjà activée et prouvée

…erdait tous les événements

sendBeacon avec un Blob application/json déclenche un preflight CORS
(application/json n'est pas un type « simple »). Firefox l'exécute puis
abandonne le POST : sendBeacon renvoie true, le repli fetch n'est jamais
atteint, et aucun événement de navigateur n'arrive au collecteur.

text/plain rend la requête « simple » : plus de preflight, beacon délivré.
Le collecteur ne contrôle pas le Content-Type (json.loads sur le corps).

Preuve navigateur réel (page https://cborweb.com, origine du site) :
- Blob application/json : preflight 204, POST jamais abouti, 0 insertion
- Blob text/plain      : aucun preflight, POST 200, insertion confirmée
- fetch (repli)        : POST 200, insertion confirmée
@ploteddie-bit
ploteddie-bit merged commit 838ae67 into main Sep 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant