Les headers HTTP forment un socle technique essentiel mais assez rarement bien maîtrisé. Cette note propose un tour d’horizon synthétique : ce qu’il faut activer, ce qu’il faut éviter, et les réglages qui amléiorent un service web
Dans la longue histoire du Web, les headers HTTP font figure d’ancêtres robustes : discrets, textuels, mais très structurants. Ils gouvernent la sécurité, le cache, la confidentialité, la négociation de formats, la performance et même l’observabilité. Pourtant, beaucoup de projets se contentent encore d’un minimum syndical, quelques directives posées par le framework ou l’hébergeur, alors que quelques en-têtes bien choisis suffisent à hausser nettement la qualité d’un service web.
Les headers utiles sont souvent connus mais sous-utilisés, et ceux qu’on oublie sont parfois ceux qui changent vraiment l’expérience, la robustesse ou l’impact environnemental d’un site ou plateforme web. Cet article fait le tri : ce qu’il faut absolument configurer, ce qu’on néglige, ce qu’il faut retirer, et les en-têtes spécialisés qui méritent d’être mieux compris.
Cette note compile des pratiques, exemples et cas d’usage concrets autour des headers HTTP. Le format est volontairement dense : blocs techniques, exemples Recommandé/À éviter, interactions importantes, particularités SPA/PWA. Pas un tutoriel, plutôt un aide-mémoire structuré.
Les headers vraiment essentiels
Headers basiques mais structurants : cache, type de contenu, garde-fous sécurité. Ils forment l’hygiène minimum, la fondation.
Cache-Control, ETag, Last-Modified
Le triptyque fondamental. Cache-Control déclare la stratégie (durée, revalidation, comportements en cas de stale). ETag et Last-Modified orchestrent les revalidations côté client. Une mauvaise cohérence entraîne des hits serveur inutiles ou un cache jamais utilisé.
Objectif : réduire les transferts, diminuer les temps de chargement.
Assets statiques versionnés (CSS/JS)
Recommandé
Cache-Control: public, max-age=31536000, immutable
ETag: "48f3-abc123"
Pourquoi : fichiers versionnés → cache long + immutable = sans risque.
À éviter
Cache-Control: no-store
→ Recharge à chaque navigation, multiplication des transferts.
Pages HTML dynamiques
Recommandé
Cache-Control: no-cache, max-age=0
→ Revalidation systématique, cohérent pour du HTML “vivant”.
À éviter
Cache-Control: public, max-age=3600
→ Risques : sessions figées, données périmées.
Images non versionnées
Recommandé
Cache-Control: public, max-age=86400, stale-while-revalidate=3600
À éviter
Cache-Control: max-age=31536000
→ Images jamais rafraîchies.
Content-Type + charset
Pilote l’interprétation du contenu. Empêche le sniffing MIME.
Recommandé
Content-Type: text/html; charset=utf-8
À éviter
Content-Type: text/html
→ Le navigateur peut interpréter, mais pas toujours de façon correcte.
Content-Security-Policy (CSP)
Le garde-corps le plus puissant côté front : limite les scripts tiers, les frames, les ressources externes et les injections.
Objectif : mitigation XSS, réduction de la surface d’attaque, maîtrise des tiers.
CSP minimale
Recommandé
Content-Security-Policy:
default-src 'self';
img-src 'self' https:;
script-src 'self';
style-src 'self' 'unsafe-inline';
object-src 'none';
frame-ancestors 'none';
CSP stricte
Recommandé
Content-Security-Policy:
default-src 'self';
script-src 'self' https://www.googletagmanager.com 'nonce-ABC123';
style-src 'self';
img-src 'self' https://cdn.example.com data:;
connect-src 'self' https://api.example.com;
frame-ancestors 'none';
base-uri 'none';
form-action 'self';
upgrade-insecure-requests;
Mauvaise CSP typique
À éviter
Content-Security-Policy: default-src * data: blob:
→ Surface d’attaque maximale. Fonctionne mais assez dangereux.
Strict-Transport-Security (HSTS)
Force le HTTPS, élimine les downgrade attacks. Peut être pré-chargé.
Recommandé
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
À éviter
Un site non 100% HTTPS avec HSTS activé trop tôt.
X-Frame-Options
Ancien contre le clickjacking. Replacé par frame-ancestors.
Referrer-Policy
Réduit la fuite d’URL sensibles.
Recommandé
Referrer-Policy: strict-origin-when-cross-origin
Les headers UX / réseau
Headers rarement configurés mais très utiles pour l’adaptation device, la sobriété réseau et la vitesse de rendu.
Accept-CH / Client Hints
Demande au navigateur d’envoyer DPR, viewport, UA platform.
Recommandé
Accept-CH: DPR, Width, Viewport-Width
Save-Data
Permet de servir une version légère aux connexions contraintes.
Recommandé
Serveur qui respecte le signal → images moins lourdes, animations allégées.
Early Hints (103)
Envoie des précharges avant la réponse finale.
Recommandé
HTTP/1.1 103 Early Hints
Link: </app.css>; rel=preload; as=style
Priority Hints
Accentue ou diminue la priorité d’un téléchargement.
Recommandé
<link rel="preload" href="/hero.webp" as="image" fetchpriority="high">
Headers pour l’observabilité, le debug et les APIs
Indispensables dans des architectures distribuées, microservices ou APIs publiques.
Server-Timing
Expose des métriques backend directement dans DevTools navaigateurs.
Recommandé
Server-Timing: db;dur=12, cache;desc="HIT"
Traceparent / Tracestate
Trace une requête de bout en bout (W3C Trace Context).
Via / X-Forwarded-* / Forwarded
Décrit la chaîne de proxys : CDN → reverse proxy → backend.
Headers ambigus, mal utilisés
Headers encore présents mais sans réelle utilité ou assez risqués.
X-Powered-By
À éviter
X-Powered-By: PHP/8.3
→ Fuite inutile.
X-XSS-Protection
À éviter
X-XSS-Protection: 1; mode=block
→ Obsolète, ignoré.
X-Content-Security-Policy
Ancienne syntaxe CSP.
Access-Control-Allow-Origin
Beaucoup trop utilisé en wildcard.
À éviter
Access-Control-Allow-Origin: *
→ Souvent non intentionnel et trop générique.
Headers spécifiques à certains usages
Cas spécialisés : médias, API versionnées, capacités navigateur.
Headers images
Accept→ AVIF/WebPContent-DPRContent-Digest
Deprecation / Sunset
Pour annoncer la fin d’une version d’API.
Permissions-Policy
Contrôle camera/micro/geo/autoplay.
Recommandé
Permissions-Policy:
camera=(),
microphone=(),
geolocation=(),
fullscreen=(self),
autoplay=(self)
À éviter
Permissions-Policy: geolocation=*
En pratique
Synthèse de configurations réalistes selon le type de projet.
Pour un site vitrine ou blog
Content-TypestrictCache-Control+ETagReferrer-Policy: strict-origin-when-cross-originX-Content-Type-Options: nosniffStrict-Transport-Security(HTTPS stable)Permissions-Policyminimale
Pour un SaaS, service public ou projet sensible
- CSP stricte (
report-only→ strict) - HSTS + preload
- CORS précis
- Client Hints
- Server-Timing + Trace Context
- Cookies Safe (Secure / SameSite)
CORS + Cookies SameSite
API avec authentification cross-site.
Recommandé
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Set-Cookie: sessionId=abc; Secure; SameSite=None
HSTS + Upgrade-Insecure-Requests
Pour une migration totale HTTPS.
Recommandé
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Content-Security-Policy: upgrade-insecure-requests
SPA (React, Vue, Svelte, Astro SPA mode)
Si un seul HTML → ne jamais mettre en cache long.
Recommandé
Cache-Control: no-cache
Assets
Cache-Control: public, max-age=31536000, immutable
PWA + Service Worker
Scope SW
Service-Worker-Allowed: /
CSP adaptée
script-src 'self' 'unsafe-eval'
Manifest Web App
Content-Type: application/manifest+json
Cache-Control: max-age=86400
Principes généraux
- Un header mal configuré est plus pénalisant qu’un header absent (donc méfiance).
- Tester via Observatory Mozilla, SecurityHeaders, DevTools.
- Bannir les wildcards génériques non intentionnels.
En bref
Maîtriser les headers HTTP, c’est garantir le contrôle d’un service web : performance, sécurité, sobriété, confidentialité et observabilité. Quelques lignes bien posées transforment la qualité d’un site sans gros effort. La meilleure approche reste incrémentale : consolider le cache, fixer la sécurité de base, puis intégrer progressivement.