Orbit
Fonctions Edge
Edge functions are small JavaScript handlers that run on Kapsule's edge network before a request reaches your project, so you can do redirects, header injection, A/B routing and bot filtering…
Les Edge functions sont de petits handlers JavaScript qui s'exécutent sur le réseau edge de Kapsule avant qu'une requête n'atteigne votre projet, ce qui vous permet d'effectuer des redirections, des injections d'en-têtes, du routage A/B et du filtrage de bots sans faire un aller-retour vers votre application. Ce guide couvre l'écriture d'une fonction, les formes de point d'entrée acceptées, la correspondance de chemin, la manière dont plusieurs fonctions interagissent, le déploiement, et ce qui se passe quand une fonction lève une exception.
Où elles se trouvent
Ouvrez votre projet dans Orbit et cliquez sur l'onglet Edge functions. Chaque fonction appartient à un projet et est répertoriée avec son badge de statut : LIVE, PAUSED, NOT DEPLOYED ou DEPLOY FAILED.

Créer une fonction
- Cliquez sur New function.
- Remplissez Name (jusqu'à 120 caractères).
- Remplissez Path pattern, le modèle d'URL sur lequel cette fonction doit s'exécuter.
- Choisissez un Trigger : Request (avant l'origine), Response (après l'origine), ou Both.
- Choisissez une Environment scope : All environments, Production only, ou Preview only.
- Écrivez le handler dans Function body.
- Cliquez sur Save, puis Deploy to edge.
L'objet request est toujours dans la portée, et la source est limitée à 64 KB.
Écrire un handler
Retournez un Response pour répondre à la requête au niveau du edge. Ne retournez rien, ou undefined, pour transmettre la requête à votre projet sans modification.
export default {
async fetch(request) {
const url = new URL(request.url)
// Redirect /old to /new
if (url.pathname === '/old') {
return new Response(null, {
status: 301,
headers: { Location: '/new' },
})
}
// Returning nothing passes through to the origin
},
}
La forme de fonction nommée fonctionne également :
export default async function handler(request) {
// Add a security header to every response
const response = await fetch(request)
const headers = new Headers(response.headers)
headers.set('X-Frame-Options', 'DENY')
return new Response(response.body, { status: response.status, headers })
}
Formes de point d'entrée supportées
| Forme | Exemple |
|---|---|
Objet avec une méthode fetch | export default { async fetch(request) { ... } } |
Objet avec une propriété arrow fetch | export default { fetch: async (request) => { ... } } |
| Déclaration de fonction nommée | export default async function handler(request) { ... } |
| Corps nu, pas d'export | Écrivez les instructions directement, sans wrapper |
Tout ce qui utilise export default, comme export default class, est rejeté quand vous cliquez sur Save, avec une erreur nommant les deux formes à utiliser à la place. La validation s'exécute au moment de la sauvegarde plutôt qu'au moment du déploiement, donc vous le découvrez immédiatement et une fonction cassée n'est jamais publiée.
Modèles de chemin
Le Path pattern décide quelles requêtes exécutent la fonction. Il doit commencer par / et peut avoir jusqu'à 2048 caractères. * correspond à n'importe quelle série de caractères et ? correspond à un seul caractère. Un modèle sans wildcard correspond exactement à ce chemin et à tout ce qui se trouve en dessous.
| Modèle | Correspond à |
|---|---|
/* | Chaque chemin |
/api/* | N'importe quoi commençant par /api/ |
/blog/*/comments | Par exemple /blog/my-post/comments |
/page | /page, et n'importe quoi sous /page/ |
L'objet request
request est une API Fetch standard Request. Vous pouvez lire l'URL, la méthode, les en-têtes et le corps :
export default {
async fetch(request) {
const url = new URL(request.url)
const cookie = request.headers.get('cookie') ?? ''
const ua = request.headers.get('user-agent') ?? ''
if (ua.includes('BadBot')) {
return new Response('Forbidden', { status: 403 })
}
},
}
Ne supposez pas qu'un en-tête existe parce que vous l'avez vu sur une autre plateforme. Lisez les en-têtes que votre propre fonction reçoit réellement (enregistrez-les à partir de la fonction, ou retournez-les dans une réponse de débogage sur un chemin jetable) avant de créer une branche basée sur l'un d'eux. Un handler qui crée une branche sur un en-tête qui n'est jamais présent prend silencieusement le mauvais chemin à chaque requête.
Modèles courants
Rediriger les anciennes URL
export default {
async fetch(request) {
const url = new URL(request.url)
const redirects = {
'/old-about': '/about',
'/old-contact': '/contact',
}
const dest = redirects[url.pathname]
if (dest) return Response.redirect(url.origin + dest, 301)
},
}
Pour une poignée de mouvements chemin-à-chemin simples, utilisez le moteur de redirection intégré à la place : il ne nécessite aucun code et est configuré dans Settings. Voir Configuring Redirects and Rewrites.
Ajouter des en-têtes de sécurité
export default async function handler(request) {
const response = await fetch(request)
const headers = new Headers(response.headers)
headers.set('X-Frame-Options', 'DENY')
headers.set('X-Content-Type-Options', 'nosniff')
headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers,
})
}
Pour les règles d'en-tête statiques, vous n'avez pas non plus besoin de code. Settings dispose d'une section d'en-têtes de réponse avec des présets d'ajout rapide pour HSTS, CSP, no-embed, no-sniff, referrer policy et CORS.
Routage A/B
export default {
async fetch(request) {
const url = new URL(request.url)
const variant = Math.random() < 0.5 ? 'a' : 'b'
url.searchParams.set('variant', variant)
return fetch(url.toString(), request)
},
}
Portée d'environnement
| Portée | S'exécute sur |
|---|---|
| All environments | Production, staging et chaque aperçu de branche |
| Production only | L'environnement de production |
| Preview only | Chaque environnement non-production |
Lancez une nouvelle fonction en tant que Preview only d'abord, confirmez qu'elle se comporte correctement sur un aperçu de branche, puis basculez-la vers All environments. Une edge function s'exécute devant chaque requête, donc une erreur dans l'une est une erreur sur chaque page à la fois.
Comment plusieurs fonctions interagissent
Toutes les fonctions activées de votre projet sont évaluées dans l'ordre dans lequel elles ont été créées. Pour chaque requête, le edge parcourt la liste et exécute la première fonction dont le modèle de chemin correspond au chemin de la requête et dont la portée couvre l'environnement.
- Si cette fonction retourne un
Response, il est envoyé et l'évaluation s'arrête. - Si elle ne retourne rien, l'évaluation continue vers la fonction correspondante suivante.
- Si aucune d'elles ne retourne un
Response, la requête va à votre projet comme d'habitude.
Cela signifie qu'une fonction large /* créée tôt peut masquer une fonction plus spécifique créée plus tard, si la fonction large retourne un Response. Créez d'abord les fonctions spécifiques, ou faites en sorte que la fonction large ne retourne rien pour les chemins qu'elle ne doit pas gérer.
Déployer
Cliquez sur Deploy to edge. Le déploiement régénère un seul routeur combiné pour tout le réseau edge à partir de l'état actuel de la base de données, donc l'activation, la désactivation, l'édition ou la suppression de n'importe quelle fonction republiera tout. Les modifications prennent généralement effet dans quelques secondes.
Chaque ligne de fonction conserve un Deploy log montrant les étapes du dernier déploiement, et un badge DEPLOY FAILED avec l'erreur s'il n'a pas réussi.
Pause retire une fonction du routeur sans la supprimer, ce qui est le moyen le plus rapide d'annuler une fonction qui se comporte mal. Resume la remet en place.
Quand une fonction lève une exception
Une exception à l'intérieur d'une fonction est capturée au niveau du edge. L'erreur est enregistrée et la requête passe à votre projet comme si la fonction n'avait rien retourné.
C'est un filet de sécurité, pas un système de surveillance. Une fonction qui lève une exception à chaque requête échoue silencieusement du point de vue de vos visiteurs, et votre trafic se comporte simplement comme si la fonction n'existait pas. Si une fonction cesse d'avoir l'effet souhaité, suspectez une exception avant de soupçonner le routage.
Limites
- Jusqu'à 20 fonctions par projet. La 21e est rejetée.
- Jusqu'à 64 KB de source par fonction.
- Jusqu'à 120 caractères pour le nom, et 2048 caractères pour le modèle de chemin.
Lectures connexes
- Configuring Redirects and Rewrites, l'option sans code pour les règles de chemin
- Deploying Your Project
- Branch Preview Deployments in Orbit pour tester une fonction avant qu'elle n'atteigne la production