Filtres de requêtes HTTP avec les fonctions Edge
Découvrez comment implémenter le filtrage des requêtes HTTP avec les fonctions AEM Edge pour réécrire ou rediriger des requêtes, ou modifier les réponses HTTP.
Quand filtrer les requêtes HTTP avec les fonctions Edge
Une fonction AEM Edge peut agir comme un proxy inverse qui effectue un traitement avancé de la requête et de la réponse avant qu’elles n’atteignent l’origine ou le client.
Les deux scénarios sont les suivants :
Ajuster la requête avant qu’elle n’atteigne l’origine
Intercepter le trafic sur le chemin de l’origine vers :
- Réécrivez l’origine, le chemin ou la requête de la requête. Acheminez la requête vers un autre serveur principal, un autre chemin d’accès ou une autre chaîne de requête afin que l’origine reçoive la ressource appropriée.
- Réécrire les en-têtes de requête. Ajoutez, supprimez ou modifiez des en-têtes avant que la requête n’atteigne l’origine. Par exemple, ajoutez une zone géographique ou un en-tête d’accès attendu par l’origine, supprimez des en-têtes que l’origine ignore ou modifiez une valeur d’en-tête pour modifier le comportement de la requête.
Modifier la réponse avant qu’elle n’atteigne le client
Intercepter le trafic sur le chemin du retour au client (visiteur) pour :
- Modifier la réponse HTML. Injectez du JavaScript, du contenu personnalisé, réécrivez des liens ou regroupez-les dans un en-tête et un pied de page avant que la page n’atteigne le navigateur.
- Redirection en périphérie. Utilisez un large ensemble de redirections d’URL héritées à nouvelles à partir du réseau CDN, en particulier lorsque les règles de redirection nécessitent une logique de programmation.
- Personnaliser par contexte de requête. Faites varier une page ou une section d’une page en fonction de la géolocalisation, de l’appareil ou de l’audience pour les visiteurs publics. Cela s’applique au trafic de publication sur votre domaine de site, et non au trafic de création.
Implémenter le filtrage des requêtes HTTP
Le filtrage des requêtes HTTP utilise deux fichiers. Le fichier config/cdn.yaml décide du trafic à intercepter et à acheminer vers votre fonction AEM Edge. Le fichier src/index.js effectue la requête ou l’ajustement de réponse.
Le sélecteur d’origine et le nom de la fonction doivent être alignés. Si edgeFunctions.yaml déclare my-edge-function, le sélecteur d’origine utilise edgefunction-my-edge-function dans cdn.yaml.
Configuration du filtre CDN
# config/cdn.yaml (origin selector excerpt)
kind: "CDN"
version: "1"
data:
originSelectors:
rules:
- name: route-to-edge-function
when:
allOf:
- { reqProperty: tier, equals: "publish" } # publish traffic only; skip author
- { reqProperty: domain, equals: "www.example.com" } # your site hostname
- { reqProperty: originalPath, matches: "(/[^./]+|\\.html|/)$" } # page URLs; skip static assets (.css, .js, images, fonts)
# - { reqProperty: method, in: ["GET", "HEAD"] } # optional: navigation only; skip POST, PUT, and other methods with bodies
- { reqHeader: x-edgefunction-request, exists: false } # skip loopback requests to prevent infinite loops
action:
type: selectAemOrigin
originName: edgefunction-my-edge-function # edgefunction-<name-of-the-function>
Si l’une des conditions échoue, la requête n’atteint jamais votre fonction AEM Edge. Commencez avec le moins de conditions dont votre fonction a besoin et ajoutez-en plus uniquement pour rendre le routage plus précis. Pour toutes les propriétés et tous les opérateurs pris en charge, voir Sélecteurs d’origine.
Mettre en œuvre le gestionnaire
Chaque fonction AEM Edge enregistre un gestionnaire d’événements de récupération. Utilisez le gestionnaire pour ajuster la requête avant qu’elle n’atteigne l’origine, pour modifier la réponse avant qu’elle n’atteigne le client, ou les deux.
Le fragment de code suivant illustre le filtrage des requêtes et la modification des réponses dans une fonction AEM Edge.
// src/index.js
addEventListener("fetch", (event) => event.respondWith(handleRequest(event)));
async function handleRequest(event) {
const req = event.request;
const url = new URL(req.url);
try {
// ------------------------------------------------------------
// --- Request filtering: adjust before origin ---
// ------------------------------------------------------------
// Example: Rewrite origin, path, or query
// Replace origin based on some criteria such as path or query
const newOriginRequest = new Request(`https://origin.example.com${url.pathname}${url.search}`);
const newOriginResponse = await fetch(newOriginRequest);
// Return the new origin response
return newOriginResponse;
...
// Example: Rewrite request headers before reaching the origin
// Add or modify headers before the request reaches the origin, like adding an authorization token based on exchange with an external service.
const originRequest = new Request(req, {
headers: new Headers({ ...Object.fromEntries(req.headers), "Authorization": "Bearer <token>" }),
});
const originResponse = await fetch(originRequest);
return originResponse;
...
// ------------------------------------------------------------
// --- Response filtering: modify before client ---
// ------------------------------------------------------------
// Example: Change response HTML (fetch from origin, transform the body)
// Fetch the response from the origin, transform the body, and return the transformed response.
const originRequest = new Request(`https://origin.example.com${url.pathname}`);
const originResponse = await fetch(originRequest);
const transformedHtml = transformHtml(await originResponse.text());
return new Response(transformedHtml, { status: 200, headers: originResponse.headers });
...
// Example: Redirect at the edge
// Redirect the client to a new path, like a legacy URL to a new URL.
return Response.redirect("https://www.example.com/new-path", 301);
...
// Example: Personalize by request context (geo, device, or audience)
// Fetch the response from the origin, personalize the body, and return the personalized response.
const originRequest = new Request(`https://origin.example.com${url.pathname}`);
const originResponse = await fetch(originRequest);
const personalizedHtml = personalizeHtml(await originResponse.text());
return new Response(personalizedHtml, { status: 200, headers: originResponse.headers });
return new Response("Not implemented", { status: 501 });
} catch (err) {
console.log(err);
return new Response("Error", { status: 500 });
}
}
Points clés :
when + allOf dans cdn.yaml itinéraires correspondant uniquement au trafic de votre fonction AEM EdgeRequest avec une origine, un chemin, une requête ou des en-têtes différents avant de fetch() à l’origineResponse avec un contenu HTML transformé, un contenu de redirection ou personnaliséfetch() internes afin que le réseau CDN achemine le trafic de bouclage vers l’origineDirectives de conception
- Gardez les filtres aussi étroits que possible.
- Limitez les fonctions de navigation à
GETetHEAD. - Évitez les boucles infinies sur la boucle CDN en définissant un en-tête sentinelle sur les appels
fetch()internes. - Déployez les
cdn.yamlmises à jour via votre pipeline de configuration Cloud Manager.
Empêcher les boucles infinies sur la boucle CDN
Une boucle infinie peut se produire lorsqu’une fonction AEM Edge récupère du contenu de l’origine via le réseau CDN. Cette récupération rentre à nouveau dans le réseau CDN, correspond à la même règle de sélecteur d’origine et revient dans la fonction .
Pour éviter cela, vous pouvez exclure les requêtes de bouclage de votre règle de sélecteur d’origine en définissant un en-tête sentinelle (par exemple, x-edgefunction-request). La demande initiale du visiteur n’a pas d’en-tête et atteint la fonction AEM Edge. La requête de bouclage transporte l’en-tête , fait échouer la condition et achemine vers l’origine à la place.
Les fragments de code et de configuration suivants montrent comment empêcher les boucles infinies sur la boucle CDN.
// src/index.js
addEventListener("fetch", (event) => event.respondWith(handleRequest(event)));
...
// In the handler: set the sentinel on the loopback fetch
const loopbackRequest = new Request(`https://www.example.com${url.pathname}`, {
headers: { "x-edgefunction-request": "true" },
});
await fetch(loopbackRequest);
Consultez les exemples de fonctions AEM Edge pour savoir comment définir l’en-tête sentinelle dans le gestionnaire de fonctions AEM Edge.
# config/cdn.yaml (origin selector excerpt)
kind: "CDN"
version: "1"
data:
originSelectors:
rules:
- name: route-to-edge-function
when:
allOf:
...
- { reqHeader: x-edgefunction-request, exists: false } # skip loopback requests to prevent infinite loops
...
Consultez les exemples de fonctions AEM Edge pour savoir comment exclure les requêtes qui portent déjà l’en-tête sentinelle dans la configuration du réseau CDN.
Exemples complets
Le référentiel Exemples de fonctions AEM Edge comprend des fonctions d’intercepteur avec des règles de config/cdn.yaml complètes :
GET/HEAD qui redirige vers une URL héritée et empêche la boucle du réseau CDNRessources supplémentaires
- Créer un point d’entrée d’API avec les fonctions Edge
- Servir plusieurs points d’entrée avec des fonctions Edge
- Configurer les fonctions AEM Edge sur AEM as a Cloud Service
- Configurer les fonctions AEM Edge sur Edge Delivery Services
- Sélecteurs d’origine
- Documentation du produit Fonctions AEM Edge
- Exemples de fonctions AEM Edge