Orbit

Edge-functies

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…

Edge functions zijn kleine JavaScript-handlers die op het edge-netwerk van Kapsule draaien voordat een verzoek je project bereikt, zodat je redirects, header-injectie, A/B-routering en bot-filtering kunt doen zonder een round trip naar je app. Deze gids behandelt het schrijven ervan, de ondersteunde entry-pointvormen, padafstemming, hoe meerdere functies samenwerken, implementatie en wat er gebeurt wanneer een functie een uitzondering genereert.

Waar ze zich bevinden

Open je project in Orbit en klik op het tabblad Edge functions. Elke functie behoort tot een project en wordt weergegeven met een statusbadge: LIVE, PAUSED, NOT DEPLOYED of DEPLOY FAILED.

Edge functions-tabblad van een Orbit-project

Een functie maken

  1. Klik op New function.
  2. Vul Name in (maximaal 120 tekens).
  3. Vul Path pattern in, het URL-patroon waarop deze functie moet worden uitgevoerd.
  4. Kies een Trigger: Request (voor origin), Response (na origin), of Both.
  5. Kies een Environment scope: All environments, Production only, of Preview only.
  6. Schrijf de handler in Function body.
  7. Klik op Save, vervolgens Deploy to edge.

Het request object is altijd in scope, en de bron is begrensd tot 64 KB.

Een handler schrijven

Retourneer een Response om het verzoek op de edge te beantwoorden. Retourneer niets, of undefined, om het verzoek onveranderd door te geven naar je project.

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
  },
}

De named-function vorm werkt ook:

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 })
}

Ondersteunde Entry-Point-vormen

VormVoorbeeld
Object met een fetch methodeexport default { async fetch(request) { ... } }
Object met een pijl fetch eigenschapexport default { fetch: async (request) => { ... } }
Named function-declaratieexport default async function handler(request) { ... }
Losse body, geen exportSchrijf de statements rechtstreeks, zonder wrapper

Alles anders dat export default gebruikt, zoals export default class, wordt geweigerd wanneer je op Save klikt, met een fout die in plaats daarvan de twee vormen noemt die je moet gebruiken. Validatie vindt plaats op het moment van opslaan in plaats van implementatie, dus je merkt het meteen en een verbroken functie wordt nooit gepubliceerd.

Padpatronen

Het Path pattern bepaalt welke verzoeken de functie uitvoeren. Het moet beginnen met / en mag maximaal 2048 tekens lang zijn. * komt overeen met elke reeks tekens en ? komt overeen met één teken. Een patroon zonder wildcard komt overeen met dat exacte pad en alles eronder.

PatroonOvereenkomsten
/*Elk pad
/api/*Alles dat begint met /api/
/blog/*/commentsBijvoorbeeld /blog/my-post/comments
/page/page, en alles onder /page/

Het request object

request is een standaard Fetch API Request. Je kunt de URL, methode, headers en body lezen:

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 })
    }
  },
}

Ga niet ervan uit dat een header bestaat omdat je deze op een ander platform hebt gezien. Lees de headers die je functie daadwerkelijk ontvangt (log ze vanuit de functie, of retourneer ze in een debug-respons op een wegwerppad) voordat je op één vertakt. Een handler die op een header vertakt die nooit aanwezig is, gaat stilzwijgend de verkeerde weg op elk verzoek.

Veelvoorkomende patronen

Oude URL's omleiden

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)
  },
}

Voor een handvol eenvoudige pad-naar-pad-verplaatsingen kunt je in plaats daarvan de ingebouwde omleidingsengine gebruiken: hiervoor is geen code nodig en deze wordt geconfigureerd in Settings. Zie Configuring Redirects and Rewrites.

Beveiligingsheaders toevoegen

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,
  })
}

Voor statische headerregels heb je ook geen code nodig. Settings heeft een responsheader-sectie met snelle opties voor HSTS, CSP, no-embed, no-sniff, referrer-beleid en CORS.

A/B-routering

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)
  },
}

Omgevingsbereik

BereikLoopt op
All environmentsProduction, staging en elke branch preview
Production onlyDe productieomgeving
Preview onlyElke niet-productieomgeving

Publiceer een nieuwe functie eerst als Preview only, bevestig dat deze correct werkt in een branch preview, schakel deze vervolgens over naar All environments. Een edge-functie loopt voor elk verzoek, dus een fout in één is een fout op elke pagina tegelijk.

Hoe meerdere functies samenwerken

Alle ingeschakelde functies van je project worden in de volgorde van creatie geëvalueerd. Voor elk verzoek loopt de edge door de lijst en voert de eerste functie uit waarvan het padpatroon overeenkomt met het verzoekpad en waarvan het bereik de omgeving dekt.

  • Als die functie een Response retourneert, wordt deze verzonden en stopt de evaluatie.
  • Als het niets retourneert, gaat de evaluatie verder naar de volgende overeenkomende functie.
  • Als geen van hen een Response retourneert, gaat het verzoek normaal naar je project.

Dit betekent dat een brede /* functie die vroeg is gemaakt, een meer specifieke kan overschaduwen die later is gemaakt, als de brede functie een Response retourneert. Maak eerst de specifieke aan, of zorg ervoor dat de brede niets retourneert voor paden die deze niet mag verwerken.

Implementatie

Klik op Deploy to edge. De implementatie genereert een enkele gecombineerde router voor het hele edge-netwerk opnieuw van de huidige databasetoestand, dus het inschakelen, uitschakelen, bewerken of verwijderen van een functie publiceert alles opnieuw. Wijzigingen treden meestal binnen enkele seconden in werking.

Elke functierij behoudt een Deploy log met de stappen van de laatste implementatie en een DEPLOY FAILED-badge met de fout als deze niet is geslaagd.

Pause verwijdert een functie uit de router zonder deze te verwijderen, wat de snelste manier is om een misbehavende functie terug te trekken. Resume zet deze terug.

Wanneer een functie een uitzondering genereert

Een uitzondering in een functie wordt op de edge onderschept. De fout wordt geregistreerd en het verzoek gaat door naar je project alsof de functie niets had geretourneerd.

Dit is een vangnet, geen controlesysteem. Een functie die op elk verzoek een uitzondering genereert, mislukt stilzwijgend vanuit het oogpunt van je bezoekers, en je verkeer werkt simpelweg alsof de functie niet bestaat. Als een functie niet langer het beoogde effect heeft, verdacht je eerst een uitzondering voordat je de routering verdacht.

Limieten

  • Tot 20 functies per project. De 21e wordt geweigerd.
  • Tot 64 KB bron per functie.
  • Tot 120 tekens voor de naam en 2048 tekens voor het padpatroon.

Aanvullende informatie

Nog steeds hulp nodig?

Stuur ons een e-mail op support@kapsulehost.com of open een chat in KPanel.

KPanel openen
Edge-functies