Menu

Server Actions und Mutationen

Server Actions sind asynchrone Funktionen, die auf dem Server ausgeführt werden. Sie können in Server- und Client-Komponenten aufgerufen werden, um Formularübermittlungen und Datenmutationen in Next.js-Anwendungen zu behandeln.

🎥 Ansehen: Erfahren Sie mehr über Mutationen mit Server Actions → YouTube (10 Minuten).

Konvention

Eine Server Action kann mit der React-Direktive "use server" definiert werden. Sie können die Direktive am Anfang einer async-Funktion platzieren, um die Funktion als Server Action zu kennzeichnen, oder am Anfang einer separaten Datei, um alle Exporte dieser Datei als Server Actions zu kennzeichnen.

Server-Komponenten

Server-Komponenten können die inline-Funktionsebene oder die Modulebene der "use server"-Direktive verwenden. Um eine Server Action inline zu definieren, fügen Sie "use server" am Anfang des Funktionskörpers hinzu:

app/page.tsx
TypeScript
export default function Page() {
  // Server Action
  async function create() {
    'use server'
    // Daten mutieren
  }
 
  return '...'
}

Client-Komponenten

Um eine Server Action in einer Client-Komponente aufzurufen, erstellen Sie eine neue Datei und fügen Sie die "use server"-Direktive am Anfang hinzu. Alle exportierten Funktionen in der Datei werden als Server Actions markiert, die sowohl in Client- als auch in Server-Komponenten wiederverwendet werden können:

app/actions.ts
TypeScript
'use server'
 
export async function create() {}
app/actions.js
'use server'
 
export async function create() {}
app/ui/button.tsx
TypeScript
'use client'
 
import { create } from '@/app/actions'
 
export function Button() {
  return <button onClick={() => create()}>Erstellen</button>
}

Übergeben von Actions als Props

Sie können auch eine Server Action als Prop an eine Client-Komponente übergeben:

<ClientComponent updateItemAction={updateItem} />
app/client-component.tsx
TypeScript
'use client'
 
export default function ClientComponent({
  updateItemAction,
}: {
  updateItemAction: (formData: FormData) => void
}) {
  return <form action={updateItemAction}>{/* ... */}</form>
}

Normalerweise würde das Next.js TypeScript-Plugin updateItemAction in client-component.tsx markieren, da es sich um eine Funktion handelt, die im Allgemeinen nicht über Client-Server-Grenzen hinweg serialisiert werden kann. Allerdings werden Props mit dem Namen action oder mit dem Suffix Action als Server Actions angenommen. Dies ist nur eine Heuristik, da das TypeScript-Plugin nicht tatsächlich weiß, ob es eine Server Action oder eine gewöhnliche Funktion erhält. Laufzeit-Typüberprüfung stellt sicher, dass Sie nicht versehentlich eine Funktion an eine Client-Komponente übergeben.

Verhalten

  • Server Actions können mit dem action-Attribut in einem <form>-Element aufgerufen werden:
    • Server-Komponenten unterstützen progressive Verbesserung standardmäßig, was bedeutet, dass das Formular auch dann übermittelt wird, wenn JavaScript noch nicht geladen wurde oder deaktiviert ist.
    • In Client-Komponenten werden Formulare, die Server Actions aufrufen, Übermittlungen in die Warteschlange stellen, wenn JavaScript noch nicht geladen wurde, und priorisieren die Client-Hydration.
    • Nach der Hydration aktualisiert der Browser die Seite bei Formularübermittlung nicht.
  • Server Actions sind nicht auf <form> beschränkt und können über Ereignishandler, useEffect, Bibliotheken von Drittanbietern und andere Formularelemente wie <button> aufgerufen werden.
  • Server Actions sind in die Next.js Caching- und Revalidierungsarchitektur integriert. Wenn eine Action aufgerufen wird, kann Next.js sowohl die aktualisierte Benutzeroberfläche als auch neue Daten in einem einzigen Server-Roundtrip zurückgeben.
  • Im Hintergrund verwenden Actions die POST-Methode, und nur diese HTTP-Methode kann sie aufrufen.
  • Die Argumente und der Rückgabewert von Server Actions müssen von React serialisierbar sein. Weitere Informationen finden Sie in den React-Dokumenten unter serialisierbare Argumente und Werte.
  • Server Actions sind Funktionen. Das bedeutet, sie können überall in Ihrer Anwendung wiederverwendet werden.
  • Server Actions erben die Laufzeit von der Seite oder dem Layout, auf dem sie verwendet werden.
  • Server Actions erben die Route Segment-Konfiguration von der Seite oder dem Layout, auf dem sie verwendet werden, einschließlich Feldern wie maxDuration.

Beispiele

Formulare

React erweitert das HTML-<form>-Element, um Server Actions mit der action-Eigenschaft aufzurufen.

Wenn sie in einem Formular aufgerufen wird, empfängt die Action automatisch das FormData-Objekt. Sie müssen kein React useState verwenden, um Felder zu verwalten. Stattdessen können Sie die Daten mit den nativen FormData-Methoden extrahieren:

app/invoices/page.tsx
TypeScript
export default function Page() {
  async function createInvoice(formData: FormData) {
    'use server'
 
    const rawFormData = {
      customerId: formData.get('customerId'),
      amount: formData.get('amount'),
      status: formData.get('status'),
    }
 
    // Daten mutieren
    // Cache revalidieren
  }
 
  return <form action={createInvoice}>...</form>
}

Hinweis:

Übergeben zusätzlicher Argumente

Sie können zusätzliche Argumente an eine Server Action mit der JavaScript-Methode bind übergeben.

app/client-component.tsx
TypeScript
'use client'
 
import { updateUser } from './actions'
 
export function UserProfile({ userId }: { userId: string }) {
  const updateUserWithId = updateUser.bind(null, userId)
 
  return (
    <form action={updateUserWithId}>
      <input type="text" name="name" />
      <button type="submit">Benutzername aktualisieren</button>
    </form>
  )
}

Die Server-Action wird zusätzlich zu den Formulardaten das Argument userId erhalten:

app/actions.js
'use server'
 
export async function updateUser(userId, formData) {}

Hinweis:

  • Eine Alternative ist, Argumente als versteckte Eingabefelder im Formular zu übergeben (z.B. <input type="hidden" name="userId" value={userId} />). Allerdings wird der Wert Teil des gerenderten HTML sein und nicht kodiert.
  • .bind funktioniert sowohl in Server- als auch in Client-Komponenten. Es unterstützt auch progressive Verbesserung.

Verschachtelte Formularelemente

Sie können eine Server-Action auch in Elementen aufrufen, die in <form> verschachtelt sind, wie z.B. <button>, <input type="submit"> und <input type="image">. Diese Elemente akzeptieren die formAction-Eigenschaft oder Ereignisbehandler.

Dies ist nützlich, wenn Sie mehrere Server-Actions innerhalb eines Formulars aufrufen möchten. Beispielsweise können Sie ein spezifisches <button>-Element zum Speichern eines Beitragentwurfs zusätzlich zum Veröffentlichen erstellen. Weitere Informationen finden Sie in den React <form>-Dokumenten.

Programmgesteuerte Formularübermittlung

Sie können eine Formularübermittlung programmgesteuert mit der requestSubmit()-Methode auslösen. Wenn der Benutzer beispielsweise ein Formular mit der Tastenkombination + Enter absendet, können Sie das onKeyDown-Ereignis abfangen:

app/entry.tsx
TypeScript
'use client'
 
export function Entry() {
  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (
      (e.ctrlKey || e.metaKey) &&
      (e.key === 'Enter' || e.key === 'NumpadEnter')
    ) {
      e.preventDefault()
      e.currentTarget.form?.requestSubmit()
    }
  }
 
  return (
    <div>
      <textarea name="entry" rows={20} required onKeyDown={handleKeyDown} />
    </div>
  )
}

Dies löst die Übermittlung des nächstgelegenen <form>-Vorfahren aus, was die Server-Action aufruft.

Serverseitige Formularvalidierung

Für grundlegende clientseitige Formularvalidierung können Sie HTML-Attribute wie required und type="email" verwenden.

Für fortgeschrittene serverseitige Validierung können Sie eine Bibliothek wie zod verwenden, um die Formularfelder vor der Datenveränderung zu validieren:

app/actions.ts
TypeScript
'use server'
 
import { z } from 'zod'
 
const schema = z.object({
  email: z.string({
    invalid_type_error: 'Ungültige E-Mail',
  }),
})
 
export default async function createUser(formData: FormData) {
  const validatedFields = schema.safeParse({
    email: formData.get('email'),
  })
 
  // Vorzeitig zurückkehren, wenn die Formulardaten ungültig sind
  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
    }
  }
 
  // Daten verändern
}

Sobald die Felder auf dem Server validiert wurden, können Sie in Ihrer Action ein serialisierbares Objekt zurückgeben und den React useFormState-Hook verwenden, um dem Benutzer eine Nachricht anzuzeigen.

  • Durch das Übergeben der Action an useFormState ändert sich die Funktionssignatur der Action, um einen neuen prevState- oder initialState-Parameter als erstes Argument zu erhalten.
  • useFormState ist ein React-Hook und muss daher in einer Client-Komponente verwendet werden.
app/actions.ts
TypeScript
'use server'
 
import { redirect } from 'next/navigation'
 
export async function createUser(prevState: any, formData: FormData) {
  const res = await fetch('https://...')
  const json = await res.json()
 
  if (!res.ok) {
    return { message: 'Bitte geben Sie eine gültige E-Mail ein' }
  }
 
  redirect('/dashboard')
}

Dann können Sie Ihre Action an den useFormState-Hook übergeben und den zurückgegebenen state verwenden, um eine Fehlermeldung anzuzeigen.

app/ui/signup.tsx
TypeScript
'use client'
 
import { useFormState } from 'react'
import { createUser } from '@/app/actions'
 
const initialState = {
  message: '',
}
 
export function Signup() {
  const [state, formAction] = useFormState(createUser, initialState)
 
  return (
    <form action={formAction}>
      <label htmlFor="email">E-Mail</label>
      <input type="text" id="email" name="email" required />
      {/* ... */}
      <p aria-live="polite">{state?.message}</p>
      <button>Registrieren</button>
    </form>
  )
}

Hinweis:

  • Diese Beispiele verwenden den React useFormState-Hook, der im Next.js App Router enthalten ist. Wenn Sie React 19 verwenden, verwenden Sie stattdessen useActionState. Weitere Informationen finden Sie in den React-Dokumenten.

Ausstehende Zustände

  • Bevor Sie Daten verändern, sollten Sie immer sicherstellen, dass ein Benutzer auch berechtigt ist, die Aktion durchzuführen. Weitere Informationen finden Sie unter Authentifizierung und Autorisierung.

Der useFormStatus-Hook stellt einen pending-Booleschen Wert bereit, der verwendet werden kann, um einen Ladeindikator anzuzeigen, während die Action ausgeführt wird.

app/submit-button.tsx
TypeScript
'use client'
 
import { useFormStatus } from 'react-dom'
 
export function SubmitButton() {
  const { pending } = useFormStatus()
 
  return (
    <button disabled={pending} type="submit">
      Registrieren
    </button>
  )
}

Hinweis:

  • In React 19 enthält useFormStatus zusätzliche Schlüssel im zurückgegebenen Objekt, wie Daten, Methode und Action. Wenn Sie nicht React 19 verwenden, ist nur der pending-Schlüssel verfügbar.
  • In React 19 enthält useActionState auch einen pending-Schlüssel im zurückgegebenen Zustand.

Optimistische Aktualisierungen

Sie können den React useOptimistic-Hook verwenden, um die Benutzeroberfläche optimistisch zu aktualisieren, bevor die Server-Action vollständig ausgeführt wird, anstatt auf die Antwort zu warten:

app/page.tsx
TypeScript
'use client'
 
import { useOptimistic } from 'react'
import { send } from './actions'
 
type Message = {
  message: string
}
 
export function Thread({ messages }: { messages: Message[] }) {
  const [optimisticMessages, addOptimisticMessage] = useOptimistic<
    Message[],
    string
  >(messages, (state, newMessage) => [...state, { message: newMessage }])
 
  const formAction = async (formData) => {
    const message = formData.get('message') as string
    addOptimisticMessage(message)
    await send(message)
  }
 
  return (
    <div>
      {optimisticMessages.map((m, i) => (
        <div key={i}>{m.message}</div>
      ))}
      <form action={formAction}>
        <input type="text" name="message" />
        <button type="submit">Senden</button>
      </form>
    </div>
  )
}

Ereignisbehandlung

Während Server-Aktionen häufig innerhalb von <form>-Elementen verwendet werden, können sie auch mit Ereignisbehandlern wie onClick aufgerufen werden. Zum Beispiel, um einen Likes-Zähler zu erhöhen:

app/like-button.tsx
TypeScript
'use client'
 
import { incrementLike } from './actions'
import { useState } from 'react'
 
export default function LikeButton({ initialLikes }: { initialLikes: number }) {
  const [likes, setLikes] = useState(initialLikes)
 
  return (
    <>
      <p>Gesamte Likes: {likes}</p>
      <button
        onClick={async () => {
          const updatedLikes = await incrementLike()
          setLikes(updatedLikes)
        }}
      >
        Like
      </button>
    </>
  )
}

Sie können auch Ereignisbehandler zu Formularelementen hinzufügen, zum Beispiel um ein Formularfeld onChange zu speichern:

app/ui/edit-post.tsx
'use client'
 
import { publishPost, saveDraft } from './actions'
 
export default function EditPost() {
  return (
    <form action={publishPost}>
      <textarea
        name="content"
        onChange={async (e) => {
          await saveDraft(e.target.value)
        }}
      />
      <button type="submit">Veröffentlichen</button>
    </form>
  )
}

Für Fälle wie diesen, in denen möglicherweise mehrere Ereignisse kurz hintereinander ausgelöst werden, empfehlen wir das Debouncing, um unnötige Server-Aktionsaufrufe zu verhindern.

useEffect

Sie können den React useEffect-Hook verwenden, um eine Server-Aktion aufzurufen, wenn die Komponente geladen wird oder sich eine Abhängigkeit ändert. Dies ist nützlich für Mutationen, die von globalen Ereignissen abhängen oder automatisch ausgelöst werden müssen. Zum Beispiel onKeyDown für App-Kurzbefehle, ein Intersection-Observer-Hook für unendliches Scrollen oder wenn die Komponente geladen wird, um einen Ansichtszähler zu aktualisieren:

app/view-count.tsx
TypeScript
'use client'
 
import { incrementViews } from './actions'
import { useState, useEffect } from 'react'
 
export default function ViewCount({ initialViews }: { initialViews: number }) {
  const [views, setViews] = useState(initialViews)
 
  useEffect(() => {
    const updateViews = async () => {
      const updatedViews = await incrementViews()
      setViews(updatedViews)
    }
 
    updateViews()
  }, [])
 
  return <p>Gesamte Aufrufe: {views}</p>
}

Denken Sie daran, das Verhalten und die Einschränkungen von useEffect zu berücksichtigen.

Fehlerbehandlung

Wenn ein Fehler auftritt, wird er vom nächstgelegenen error.js oder <Suspense>-Boundary auf der Clientseite abgefangen. Wir empfehlen die Verwendung von try/catch, um Fehler zurückzugeben, die von Ihrer Benutzeroberfläche behandelt werden können.

Beispielsweise könnte Ihre Server-Aktion Fehler beim Erstellen eines neuen Elements behandeln, indem sie eine Nachricht zurückgibt:

app/actions.ts
'use server'
 
export async function createTodo(prevState: any, formData: FormData) {
  try {
    // Daten mutieren
  } catch (e) {
    throw new Error('Fehler beim Erstellen der Aufgabe')
  }
}
app/actions.js
'use server'
 
export async function createTodo(prevState, formData) {
  try {
    // Daten mutieren
  } catch (e) {
    throw new Error('Fehler beim Erstellen der Aufgabe')
  }
}

Hinweis:

Daten erneut validieren

Sie können den Next.js-Cache in Ihren Server-Aktionen mit der revalidatePath-API erneut validieren:

app/actions.ts
'use server'
 
import { revalidatePath } from 'next/cache'
 
export async function createPost() {
  try {
    // ...
  } catch (error) {
    // ...
  }
 
  revalidatePath('/posts')
}
app/actions.js
'use server'
 
import { revalidatePath } from 'next/cache'
 
export async function createPost() {
  try {
    // ...
  } catch (error) {
    // ...
  }
 
  revalidatePath('/posts')
}

Oder invalidieren Sie einen spezifischen Datenabruf mit einem Cache-Tag mithilfe von revalidateTag:

app/actions.ts
'use server'
 
import { revalidateTag } from 'next/cache'
 
export async function createPost() {
  try {
    // ...
  } catch (error) {
    // ...
  }
 
  revalidateTag('posts')
}
app/actions.js
'use server'
 
import { revalidateTag } from 'next/cache'
 
export async function createPost() {
  try {
    // ...
  } catch (error) {
    // ...
  }
 
  revalidateTag('posts')
}

Weiterleiten

Wenn Sie den Benutzer nach Abschluss einer Server-Aktion auf eine andere Route weiterleiten möchten, können Sie die redirect-API verwenden. redirect muss außerhalb des try/catch-Blocks aufgerufen werden:

app/actions.ts
'use server'
 
import { redirect } from 'next/navigation'
import { revalidateTag } from 'next/cache'
 
export async function createPost(id: string) {
  try {
    // ...
  } catch (error) {
    // ...
  }
 
  revalidateTag('posts') // Zwischengespeicherte Beiträge aktualisieren
  redirect(`/post/${id}`) // Zur neuen Beitragsseite navigieren
}
app/actions.js
'use server'
 
import { redirect } from 'next/navigation'
import { revalidateTag } from 'next/cache'
 
export async function createPost(id) {
  try {
    // ...
  } catch (error) {
    // ...
  }
 
  revalidateTag('posts') // Zwischengespeicherte Beiträge aktualisieren
  redirect(`/post/${id}`) // Zur neuen Beitragsseite navigieren
}

Cookies

Sie können Cookies in einer Server-Aktion mit der cookies-API abrufen, festlegen und löschen:

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function exampleAction() {
  const cookieStore = await cookies()
 
  // Cookie abrufen
  cookieStore.get('name')?.value
 
  // Cookie festlegen
  cookieStore.set('name', 'Delba')
 
  // Cookie löschen
  cookieStore.delete('name')
}
app/actions.js
'use server'
 
import { cookies } from 'next/headers'
 
export async function exampleAction() {
  // Cookie abrufen
  const cookieStore = await cookies()
 
  // Cookie abrufen
  cookieStore.get('name')?.value
 
  // Cookie festlegen
  cookieStore.set('name', 'Delba')
 
  // Cookie löschen
  cookieStore.delete('name')
}

Weitere Beispiele zum Löschen von Cookies aus Server-Aktionen finden Sie hier.

Sicherheit

Standardmäßig erstellt eine Server-Aktion bei ihrer Erstellung und beim Exportieren einen öffentlichen HTTP-Endpunkt und sollte mit den gleichen Sicherheitsannahmen und Autorisierungsüberprüfungen behandelt werden. Das bedeutet, selbst wenn eine Server-Aktion oder Hilfsfunktion an anderer Stelle in Ihrem Code nicht importiert wird, ist sie dennoch öffentlich zugänglich.

Um die Sicherheit zu verbessern, bietet Next.js die folgenden integrierten Funktionen:

  • Sichere Aktions-IDs: Next.js erstellt verschlüsselte, nicht-deterministische IDs, um dem Client zu ermöglichen, auf die Server-Aktion zu verweisen und sie aufzurufen. Diese IDs werden zwischen den Builds periodisch neu berechnet, um die Sicherheit zu erhöhen.
  • Dead-Code-Elimination: Ungenutzte Server-Aktionen (über ihre IDs referenziert) werden aus dem Client-Bundle entfernt, um den öffentlichen Zugriff durch Dritte zu vermeiden.

Hinweis:

Die IDs werden während der Kompilierung erstellt und für maximal 14 Tage zwischengespeichert. Sie werden neu generiert, wenn ein neuer Build gestartet oder der Build-Cache invalidiert wird. Diese Sicherheitsverbesserung reduziert das Risiko in Fällen, in denen eine Authentifizierungsschicht fehlt. Dennoch sollten Sie Server-Aktionen wie öffentliche HTTP-Endpunkte behandeln.

// app/actions.js
'use server'
 
// Diese Aktion **wird** in unserer Anwendung verwendet, sodass Next.js
// eine sichere ID erstellt, damit der Client die Server-Aktion
// referenzieren und aufrufen kann.
export async function updateUserAction(formData) {}
 
// Diese Aktion **wird nicht** in unserer Anwendung verwendet, sodass Next.js
// diesen Code während `next build` automatisch entfernt
// und keinen öffentlichen Endpunkt erstellt.
export async function deleteUserAction(formData) {}

Authentifizierung und Autorisierung

Sie sollten sicherstellen, dass der Benutzer berechtigt ist, die Aktion durchzuführen. Zum Beispiel:

app/actions.ts
'use server'
 
import { auth } from './lib'
 
export function addItem() {
  const { user } = auth()
  if (!user) {
    throw new Error('Sie müssen angemeldet sein, um diese Aktion durchzuführen')
  }
 
  // ...
}

Closures und Verschlüsselung

Das Definieren einer Server-Aktion innerhalb einer Komponente erstellt einen Closure, bei dem die Aktion auf den Gültigkeitsbereich der äußeren Funktion zugreifen kann. Zum Beispiel hat die publish-Aktion Zugriff auf die publishVersion-Variable:

app/page.tsx
TypeScript
export default async function Page() {
  const publishVersion = await getLatestVersion();
 
  async function publish() {
    "use server";
    if (publishVersion !== await getLatestVersion()) {
      throw new Error('Die Version hat sich seit dem Drücken von "Veröffentlichen" geändert');
    }
    ...
  }
 
  return (
    <form>
      <button formAction={publish}>Veröffentlichen</button>
    </form>
  );
}

Closures sind nützlich, wenn Sie eine Momentaufnahme von Daten (z.B. publishVersion) zum Zeitpunkt des Renderns erfassen müssen, damit sie später bei Aufruf der Aktion verwendet werden kann.

Damit dies funktioniert, werden die erfassten Variablen an den Client gesendet und zurück zum Server, wenn die Aktion aufgerufen wird. Um zu verhindern, dass sensible Daten dem Client offengelegt werden, verschlüsselt Next.js automatisch die in der Closure erfassten Variablen. Für jede Aktion wird bei jedem Build einer Next.js-Anwendung ein neuer privater Schlüssel generiert. Das bedeutet, dass Aktionen nur für einen bestimmten Build aufgerufen werden können.

Hinweis: Wir empfehlen nicht, sich allein auf Verschlüsselung zu verlassen, um zu verhindern, dass sensible Werte dem Client offengelegt werden. Stattdessen sollten Sie die React-Taint-APIs verwenden, um proaktiv zu verhindern, dass bestimmte Daten an den Client gesendet werden.

Überschreiben von Verschlüsselungsschlüsseln (erweitert)

Wenn Sie Ihre Next.js-Anwendung auf mehreren Servern selbst hosten, kann jede Serverinstanz einen anderen Verschlüsselungsschlüssel erhalten, was zu potenziellen Inkonsistenzen führen kann.

Um dies zu mildern, können Sie den Verschlüsselungsschlüssel mithilfe der Umgebungsvariablen process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY überschreiben. Das Angeben dieser Variablen stellt sicher, dass Ihre Verschlüsselungsschlüssel über Builds hinweg persistent sind und alle Serverinstanzen denselben Schlüssel verwenden.

Dies ist ein fortgeschrittener Anwendungsfall, bei dem ein konsistentes Verschlüsselungsverhalten über mehrere Bereitstellungen hinweg für Ihre Anwendung kritisch ist. Sie sollten Standardsicherheitspraktiken wie Schlüsselrotation und -signatur berücksichtigen.

Hinweis: Next.js-Anwendungen, die auf Vercel bereitgestellt werden, behandeln dies automatisch.

Erlaubte Ursprünge (erweitert)

Da Server-Aktionen in einem <form>-Element aufgerufen werden können, öffnen sie sich für CSRF-Angriffe.

Im Hintergrund verwenden Server-Aktionen die POST-Methode, und nur diese HTTP-Methode ist erlaubt, um sie aufzurufen. Dies verhindert die meisten CSRF-Sicherheitslücken in modernen Browsern, insbesondere da SameSite-Cookies standardmäßig verwendet werden.

Als zusätzlicher Schutz vergleichen Server-Aktionen in Next.js auch den Origin-Header mit dem Host-Header (oder X-Forwarded-Host). Wenn diese nicht übereinstimmen, wird die Anfrage abgebrochen. Mit anderen Worten: Server-Aktionen können nur auf demselben Host aufgerufen werden, auf dem die Seite gehostet wird.

Für große Anwendungen, die Reverse-Proxys oder mehrschichtige Backend-Architekturen verwenden (bei denen die Server-API von der Produktionsdomäne abweicht), wird empfohlen, die Konfigurationsoption serverActions.allowedOrigins zu verwenden, um eine Liste sicherer Ursprünge anzugeben. Die Option akzeptiert ein Array von Strings.

next.config.js
/** @type {import('next').NextConfig} */
module.exports = {
  experimental: {
    serverActions: {
      allowedOrigins: ['my-proxy.com', '*.my-proxy.com'],
    },
  },
}

Weitere Informationen zu Sicherheit und Server-Aktionen.

Zusätzliche Ressourcen

Weitere Informationen finden Sie in den folgenden React-Dokumenten:

下一步

Erfahren Sie, wie Sie Server Actions in Next.js konfigurieren