Orbit

Edge-Funktionen

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 sind kleine JavaScript-Handler, die auf Kapsules Edge-Netzwerk ausgeführt werden, bevor eine Anfrage Ihr Projekt erreicht. Sie können damit Weiterleitungen, Header-Injektionen, A/B-Routing und Bot-Filterung durchführen, ohne dass die Anfrage zu Ihrer App hin und zurück gehen muss. Dieser Leitfaden behandelt das Schreiben einer Funktion, akzeptierte Entry-Point-Formulare, Pfad-Matching, die Interaktion mehrerer Funktionen, die Bereitstellung und was passiert, wenn eine Funktion einen Fehler wirft.

Wo sie sich befinden

Öffnen Sie Ihr Projekt in Orbit und klicken Sie auf die Registerkarte Edge functions. Jede Funktion gehört zu einem Projekt und wird mit ihrem Status-Badge aufgelistet: LIVE, PAUSED, NOT DEPLOYED oder DEPLOY FAILED.

Registerkarte „Edge functions" eines Orbit-Projekts

Eine Funktion erstellen

  1. Klicken Sie auf New function.
  2. Füllen Sie Name aus (bis zu 120 Zeichen).
  3. Füllen Sie Path pattern aus, das URL-Muster, auf dem diese Funktion ausgeführt werden soll.
  4. Wählen Sie einen Trigger: Request (before origin), Response (after origin) oder Both.
  5. Wählen Sie einen Environment scope: All environments, Production only oder Preview only.
  6. Schreiben Sie den Handler in Function body.
  7. Klicken Sie auf Save, dann auf Deploy to edge.

Das request Objekt ist immer im Geltungsbereich vorhanden, und die Quelle ist auf 64 KB begrenzt.

Einen Handler schreiben

Geben Sie ein Response zurück, um die Anfrage am Edge zu beantworten. Geben Sie nichts zurück, oder undefined, um die Anfrage unverändert an Ihr Projekt weiterzuleiten.

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

Die Named-Function-Form funktioniert auch:

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

Unterstützte Entry-Point-Formulare

FormulareBeispiel
Objekt mit einer fetch Methodeexport default { async fetch(request) { ... } }
Objekt mit einer Arrow-fetch Eigenschaftexport default { fetch: async (request) => { ... } }
Named Function Declarationexport default async function handler(request) { ... }
Bare Body, kein ExportSchreiben Sie die Anweisungen direkt auf, ohne Wrapper

Alles andere, das export default verwendet, wie z. B. export default class, wird beim Klick auf Save abgelehnt, mit einem Fehler, der die beiden zu verwendenden Formulare benennt. Die Validierung läuft zum Zeitpunkt des Speicherns statt zum Zeitpunkt der Bereitstellung ab, sodass Sie sofort Bescheid wissen und eine fehlerhafte Funktion wird niemals veröffentlicht.

Pfad-Muster

Das Path pattern entscheidet, welche Anfragen die Funktion ausführen. Es muss mit / beginnen und kann bis zu 2048 Zeichen lang sein. * passt zu jeder beliebigen Zeichenkette und ? passt zu einem einzelnen Zeichen. Ein Muster ohne Wildcard passt zu diesem exakten Pfad und allem darunter.

MusterPasst zu
/*Jedem Pfad
/api/*Alles, das mit /api/ beginnt
/blog/*/commentsZum Beispiel /blog/my-post/comments
/page/page und alles darunter /page/

Das request Objekt

request ist ein Standard Fetch API Request. Sie können die URL, die Methode, Header und den Body lesen:

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

Nehmen Sie nicht an, dass ein Header vorhanden ist, weil Sie ihn auf einer anderen Plattform gesehen haben. Lesen Sie die Header, die Ihre eigene Funktion tatsächlich erhält (protokollieren Sie sie aus der Funktion oder geben Sie sie in einer Debug-Antwort auf einem Wegwerf-Pfad zurück), bevor Sie einen Branch basierend auf einem erstellen. Ein Handler, der auf einen Header verzweigt, der nie vorhanden ist, nimmt auf jeder Anfrage stillschweigend den falschen Pfad.

Allgemeine Muster

Alte URLs umleiten

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

Verwenden Sie für eine Handvoll einfacher Pfad-zu-Pfad-Verschiebungen stattdessen die integrierte Redirect-Engine: Sie benötigt keinen Code und wird in den Einstellungen konfiguriert. Siehe Configuring Redirects and Rewrites.

Sicherheits-Header hinzufügen

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

Für statische Header-Regeln benötigen Sie auch keinen Code. Settings verfügt über einen Response-Header-Bereich mit Quick-Add-Voreinstellungen für HSTS, CSP, no-embed, no-sniff, Referrer-Richtlinie und CORS.

A/B-Routing

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

Environment Scope

GeltungsbereichLäuft auf
All environmentsProduction, Staging und alle Branch Previews
Production onlyDie Production-Umgebung
Preview onlyJede Non-Production-Umgebung

Stellen Sie eine neue Funktion zunächst als Preview only bereit, bestätigen Sie das Verhalten in einer Branch Preview und wechseln Sie dann zu All environments. Eine Edge Function wird vor jeder Anfrage ausgeführt, daher ist ein Fehler in einer ein Fehler auf jeder Seite auf einmal.

Wie mehrere Funktionen zusammenwirken

Alle aktivierten Funktionen Ihres Projekts werden in der Reihenfolge ihrer Erstellung ausgewertet. Für jede Anfrage durchläuft der Edge die Liste und führt die erste Funktion aus, deren Pfad-Muster zum Anfragepfad passt und deren Geltungsbereich die Umgebung abdeckt.

  • Wenn diese Funktion ein Response zurückgibt, wird es gesendet und die Auswertung stoppt.
  • Wenn es nichts zurückgibt, wird die Auswertung mit der nächsten passenden Funktion fortgesetzt.
  • Wenn keine von ihnen ein Response zurückgibt, geht die Anfrage normal zu Ihrem Projekt.

Das bedeutet, dass eine breite /* Funktion, die früh erstellt wurde, eine spätere, schmalere überschatten kann, wenn die breite Funktion ein Response zurückgibt. Erstellen Sie die spezifischen zuerst, oder lassen Sie die breite Funktion nichts für Pfade zurückgeben, die sie nicht handhaben sollte.

Bereitstellen

Klicken Sie auf Deploy to edge. Die Bereitstellung regeneriert einen einzigen kombinierten Router für das gesamte Edge-Netzwerk aus dem aktuellen Status der Datenbank, sodass das Aktivieren, Deaktivieren, Bearbeiten oder Löschen einer Funktion alles erneut veröffentlicht. Änderungen treten normalerweise innerhalb weniger Sekunden in Kraft.

Jede Funktionszeile behält ein Deploy log, das die Schritte der letzten Bereitstellung zeigt, und einen DEPLOY FAILED Badge mit dem Fehler, falls er nicht erfolgreich war.

Pause entfernt eine Funktion aus dem Router, ohne sie zu löschen, was die schnellste Möglichkeit ist, eine fehlerhafte Funktion rückgängig zu machen. Resume setzt sie wieder ein.

Wenn eine Funktion einen Fehler wirft

Eine Ausnahme in einer Funktion wird am Edge abgefangen. Der Fehler wird protokolliert und die Anfrage wird an Ihr Projekt weitergeleitet, als ob die Funktion nichts zurückgegeben hätte.

Dies ist ein Sicherheitsnetz, kein Überwachungssystem. Eine Funktion, die bei jeder Anfrage einen Fehler wirft, schlägt aus Sicht Ihrer Besucher stillschweigend fehl, und Ihr Traffic verhält sich einfach so, als würde die Funktion nicht existieren. Wenn eine Funktion ihre beabsichtigte Wirkung nicht mehr hat, verdächtigen Sie zuerst eine Ausnahme, bevor Sie das Routing verdächtigen.

Grenzwerte

  • Bis zu 20 Funktionen pro Projekt. Die 21. wird abgelehnt.
  • Bis zu 64 KB Quellcode pro Funktion.
  • Bis zu 120 Zeichen für den Namen und 2048 Zeichen für das Pfad-Muster.

Weiterführende Lektüre

Benötigen Sie noch Hilfe?

Schreiben Sie uns an support@kapsulehost.com oder öffnen Sie einen Chat in KPanel.

KPanel öffnen
Edge-Funktionen