Presenter
Wir werden lernen, wie man Presenter und Templates in Nette schreibt. Nach dem Lesen werden Sie wissen:
- wie ein Presenter funktioniert
- was persistente Parameter sind
- wie Templates gerendert werden
Wir wissen bereits, dass ein Presenter eine Klasse ist, die eine bestimmte Seite einer Webanwendung repräsentiert, z. B. die Homepage, ein Produkt in einem E-Shop, ein Anmeldeformular, einen Sitemap-Feed usw. Eine Anwendung kann einen bis tausende Presenter haben. In anderen Frameworks werden sie auch Controller genannt.
Normalerweise ist mit dem Begriff Presenter ein Nachkomme der Klasse Nette\Application\UI\Presenter gemeint, der für die Generierung von Weboberflächen geeignet ist und dem wir uns im Rest dieses Kapitels widmen werden. Im allgemeinen Sinn ist ein Presenter jedes Objekt, das das Interface Nette\Application\IPresenter implementiert.
Lebenszyklus des Presenters
Die Aufgabe des Presenters ist es, eine Anfrage zu bearbeiten und eine Antwort zurückzugeben (dies kann eine HTML-Seite, ein Bild, eine Weiterleitung usw. sein).
Zu Beginn wird ihm also eine Anfrage übergeben. Dies ist keine direkte HTTP-Anfrage, sondern ein Objekt Nette\Application\Request, in das die HTTP-Anfrage mithilfe des Routers umgewandelt wurde. Mit diesem Objekt kommen wir normalerweise nicht in Berührung, da der Presenter die Verarbeitung der Anfrage geschickt an weitere Methoden delegiert, die wir uns jetzt ansehen werden.
Das Bild zeigt eine Liste von Methoden, die der Reihe nach von oben nach unten aufgerufen werden, sofern sie existieren. Keine davon muss existieren, wir können einen völlig leeren Presenter ohne eine einzige Methode haben und darauf eine einfache statische Website aufbauen.
__construct()
Der Konstruktor gehört nicht ganz zum Lebenszyklus des Presenters, da er im Moment der Objekterstellung aufgerufen wird. Aber wir erwähnen ihn wegen seiner Wichtigkeit. Der Konstruktor (zusammen mit der inject-Methode) dient zur Übergabe von Abhängigkeiten.
Ein Presenter sollte nicht die Geschäftslogik der Anwendung handhaben, aus der Datenbank schreiben und lesen, Berechnungen
durchführen usw. Dafür gibt es Klassen aus der Schicht, die wir als Model bezeichnen. Zum Beispiel kann die Klasse
ArticleRepository
für das Laden und Speichern von Artikeln zuständig sein. Damit der Presenter damit arbeiten kann,
lässt er sie sich mittels Dependency Injection
übergeben:
class ArticlePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private ArticleRepository $articles,
) {
}
}
startup()
Unmittelbar nach Erhalt der Anfrage wird die Methode startup()
aufgerufen. Sie können sie zur Initialisierung von
Properties, zur Überprüfung von Benutzerberechtigungen usw. verwenden. Es ist erforderlich, dass die Methode immer den Vorfahren
parent::startup()
aufruft.
action<Action>(args...)
Ähnlich der Methode render<View>()
. Während render<View>()
dazu dient, Daten für ein
bestimmtes Template vorzubereiten, das anschließend gerendert wird, wird in action<Action>()
die Anfrage ohne
Bezug zum Rendern des Templates verarbeitet. Zum Beispiel werden Daten verarbeitet, der Benutzer an- oder abgemeldet usw., und
danach woandershin weitergeleitet.
Wichtig ist, dass action<Action>()
vor render<View>()
aufgerufen wird, sodass wir darin
gegebenenfalls den weiteren Verlauf ändern können, d.h. das zu rendernde Template und auch die aufzurufende
render<View>()
-Methode ändern können. Und zwar mittels setView('anderesView')
.
Der Methode werden Parameter aus der Anfrage übergeben. Es ist möglich und empfohlen, den Parametern Typen anzugeben, z.B.
actionShow(int $id, ?string $slug = null)
– wenn der Parameter id
fehlt oder kein Integer ist, gibt
der Presenter einen Fehler 404 zurück und beendet die Tätigkeit.
handle<Signal>(args...)
Diese Methode verarbeitet sogenannte Signale, die wir im Kapitel über Komponenten kennenlernen werden. Sie ist nämlich hauptsächlich für Komponenten und die Verarbeitung von AJAX-Anfragen gedacht.
Der Methode werden Parameter aus der Anfrage übergeben, wie im Fall von action<Action>()
, einschließlich
Typüberprüfung.
beforeRender()
Die Methode beforeRender
, wie der Name schon sagt, wird vor jeder render<View>()
-Methode
aufgerufen. Sie wird für die gemeinsame Konfiguration des Templates, die Übergabe von Variablen für das Layout und ähnliches
verwendet.
render<View>(args...)
Der Ort, an dem wir das Template für das anschließende Rendern vorbereiten, ihm Daten übergeben usw.
Der Methode werden Parameter aus der Anfrage übergeben, wie im Fall von action<Action>()
, einschließlich
Typüberprüfung.
public function renderShow(int $id): void
{
// Wir holen Daten aus dem Model und übergeben sie an das Template
$this->template->article = $this->articles->getById($id);
}
afterRender()
Die Methode afterRender
, wie der Name wiederum andeutet, wird nach jeder render<View>()
-Methode
aufgerufen. Sie wird eher selten verwendet.
shutdown()
Wird am Ende des Lebenszyklus des Presenters aufgerufen.
Ein guter Rat, bevor wir weitermachen. Ein Presenter kann, wie man sieht, mehrere Aktionen/Views bedienen, also mehrere
render<View>()
-Methoden haben. Wir empfehlen jedoch, Presenter mit einer oder möglichst wenigen Aktionen zu
entwerfen.
Senden der Antwort
Die Antwort des Presenters ist normalerweise das Rendern eines Templates mit einer HTML-Seite, es kann aber auch das Senden einer Datei, JSON oder eine Weiterleitung zu einer anderen Seite sein.
Wir können jederzeit während des Lebenszyklus mit einer der folgenden Methoden eine Antwort senden und gleichzeitig den Presenter beenden:
redirect()
,redirectPermanent()
,redirectUrl()
undforward()
leiten weitererror()
beendet den Presenter aufgrund eines FehlerssendJson($data)
beendet den Presenter und sendet Daten im JSON-FormatsendTemplate()
beendet den Presenter und rendert sofort das TemplatesendResponse($response)
beendet den Presenter und sendet eine eigene Antwortterminate()
beendet den Presenter ohne Antwort
Wenn Sie keine dieser Methoden aufrufen, greift der Presenter automatisch auf das Rendern des Templates zurück. Warum? Weil wir in 99 % der Fälle ein Template rendern möchten, daher betrachtet der Presenter dieses Verhalten als Standard und möchte uns die Arbeit erleichtern.
Erstellen von Links
Der Presenter verfügt über die Methode link()
, mit der URL-Links zu anderen Presentern erstellt werden können.
Der erste Parameter ist der Ziel-Presenter & Aktion, gefolgt von den übergebenen Argumenten, die als Array angegeben werden
können:
$url = $this->link('Product:show', $id);
$url = $this->link('Product:show', [$id, 'lang' => 'cs']);
Im Template werden Links zu anderen Presentern & Aktionen auf diese Weise erstellt:
<a n:href="Product:show $id">Produktdetail</a>
Statt der echten URL schreiben Sie einfach das bekannte Paar Presenter:action
und geben eventuelle Parameter an.
Der Trick liegt in n:href
, das besagt, dass dieses Attribut von Latte verarbeitet wird und die echte URL generiert.
In Nette müssen Sie also überhaupt nicht über URLs nachdenken, nur über Presenter und Aktionen.
Weitere Informationen finden Sie im Kapitel Erstellen von URL-Links.
Weiterleitung
Zum Wechsel zu einem anderen Presenter dienen die Methoden redirect()
und forward()
, die eine sehr
ähnliche Syntax wie die Methode link() haben.
Die Methode forward()
wechselt sofort zum neuen Presenter ohne HTTP-Weiterleitung:
$this->forward('Product:show');
Ein Beispiel für eine sogenannte temporäre Weiterleitung mit dem HTTP-Code 302 (oder 303, wenn die Methode der aktuellen Anfrage POST ist):
$this->redirect('Product:show', $id);
Eine permanente Weiterleitung mit dem HTTP-Code 301 erreichen Sie so:
$this->redirectPermanent('Product:show', $id);
Zu einer anderen URL außerhalb der Anwendung kann mit der Methode redirectUrl()
weitergeleitet werden. Als
zweiter Parameter kann der HTTP-Code angegeben werden, Standard ist 302 (oder 303, wenn die Methode der aktuellen Anfrage
POST ist):
$this->redirectUrl('https://nette.org');
Die Weiterleitung beendet sofort die Tätigkeit des Presenters durch Auslösen der sogenannten stillen Beendigungs-Ausnahme
Nette\Application\AbortException
.
Vor der Weiterleitung können Flash-Nachrichten gesendet werden, also Nachrichten, die nach der Weiterleitung im Template angezeigt werden.
Flash-Nachrichten
Dies sind Nachrichten, die normalerweise über das Ergebnis einer Operation informieren. Ein wichtiges Merkmal von Flash-Nachrichten ist, dass sie auch nach einer Weiterleitung im Template verfügbar sind. Auch nach der Anzeige bleiben sie noch weitere 30 Sekunden aktiv – zum Beispiel für den Fall, dass der Benutzer aufgrund einer fehlerhaften Übertragung die Seite neu lädt – die Nachricht verschwindet also nicht sofort.
Rufen Sie einfach die Methode flashMessage() auf, und
der Presenter kümmert sich um die Übergabe an das Template. Der erste Parameter ist der Text der Nachricht und der optionale
zweite Parameter ihr Typ (error, warning, info usw.). Die Methode flashMessage()
gibt eine Instanz der
Flash-Nachricht zurück, der weitere Informationen hinzugefügt werden können.
$this->flashMessage('Der Eintrag wurde gelöscht.');
$this->redirect(/* ... */); // und wir leiten weiter
Im Template stehen diese Nachrichten in der Variable $flashes
als stdClass
-Objekte zur Verfügung,
die die Eigenschaften message
(Nachrichtentext), type
(Nachrichtentyp) enthalten und die bereits
erwähnten Benutzerinformationen enthalten können. Wir rendern sie zum Beispiel so:
{foreach $flashes as $flash}
<div class="flash {$flash->type}">{$flash->message}</div>
{/foreach}
Fehler 404 und Co.
Wenn die Anfrage nicht erfüllt werden kann, zum Beispiel weil der Artikel, den wir anzeigen möchten, nicht in der Datenbank
existiert, werfen wir einen 404-Fehler mit der Methode error(?string $message = null, int $httpCode = 404)
aus.
public function renderShow(int $id): void
{
$article = $this->articles->getById($id);
if (!$article) {
$this->error();
}
// ...
}
Der HTTP-Fehlercode kann als zweiter Parameter übergeben werden, Standard ist 404. Die Methode funktioniert so, dass sie die
Ausnahme Nette\Application\BadRequestException
auslöst, woraufhin die Application
die Steuerung an den
Error-Presenter übergibt. Dies ist ein Presenter, dessen Aufgabe es ist, eine Seite anzuzeigen, die über den aufgetretenen
Fehler informiert. Die Einstellung des Error-Presenters erfolgt in der Anwendungskonfiguration.
Senden von JSON
Ein Beispiel für eine Action-Methode, die Daten im JSON-Format sendet und den Presenter beendet:
public function actionData(): void
{
$data = ['hello' => 'nette'];
$this->sendJson($data);
}
Anfrageparameter
Der Presenter und auch jede Komponente erhalten ihre Parameter aus der HTTP-Anfrage. Ihren Wert erhalten Sie mit der Methode
getParameter($name)
oder getParameters()
. Die Werte sind Zeichenketten oder Arrays von Zeichenketten, es
handelt sich im Grunde um Rohdaten, die direkt aus der URL stammen.
Für mehr Komfort empfehlen wir, die Parameter über Properties zugänglich zu machen. Markieren Sie sie einfach mit dem
Attribut #[Parameter]
:
use Nette\Application\Attributes\Parameter; // diese Zeile ist wichtig
class HomePresenter extends Nette\Application\UI\Presenter
{
#[Parameter]
public string $theme; // muss public sein
}
Bei der Property empfehlen wir, auch den Datentyp anzugeben (z.B. string
), und Nette wandelt den Wert entsprechend
automatisch um. Die Parameterwerte können auch validiert werden.
Beim Erstellen eines Links kann der Wert der Parameter direkt festgelegt werden:
<a n:href="Home:default theme: dark">klicken</a>
Persistente Parameter
Persistente Parameter dienen dazu, den Zustand zwischen verschiedenen Anfragen aufrechtzuerhalten. Ihr Wert bleibt auch nach
dem Klicken auf einen Link gleich. Im Gegensatz zu Daten in der Session werden sie in der URL übertragen. Und das völlig
automatisch, es ist also nicht notwendig, sie explizit in link()
oder n:href
anzugeben.
Ein Anwendungsbeispiel? Sie haben eine mehrsprachige Anwendung. Die aktuelle Sprache ist ein Parameter, der ständig Teil der
URL sein muss. Aber es wäre unglaublich mühsam, ihn in jedem Link anzugeben. Also machen Sie daraus einen persistenten Parameter
lang
, und er wird von selbst übertragen. Großartig!
Das Erstellen eines persistenten Parameters ist in Nette extrem einfach. Erstellen Sie einfach eine öffentliche Property und
markieren Sie sie mit einem Attribut: (früher wurde /** @persistent */
verwendet)
use Nette\Application\Attributes\Persistent; // diese Zeile ist wichtig
class ProductPresenter extends Nette\Application\UI\Presenter
{
#[Persistent]
public string $lang; // muss public sein
}
Wenn $this->lang
beispielsweise den Wert 'en'
hat, dann werden auch Links, die mit
link()
oder n:href
erstellt wurden, den Parameter lang=en
enthalten. Und nach dem Klicken
auf den Link wird wieder $this->lang = 'en'
sein.
Bei der Property empfehlen wir, auch den Datentyp anzugeben (z.B. string
), und Sie können auch einen Standardwert
angeben. Die Parameterwerte können validiert werden.
Persistente Parameter werden standardmäßig zwischen allen Aktionen des jeweiligen Presenters übertragen. Damit sie auch zwischen mehreren Presentern übertragen werden, müssen sie entweder definiert werden:
- in einem gemeinsamen Vorfahren, von dem die Presenter erben
- in einem Trait, den die Presenter verwenden:
trait LanguageAware
{
#[Persistent]
public string $lang;
}
class ProductPresenter extends Nette\Application\UI\Presenter
{
use LanguageAware;
}
Beim Erstellen eines Links kann der Wert eines persistenten Parameters geändert werden:
<a n:href="Product:show $id, lang: cs">Detail auf Tschechisch</a>
Oder er kann zurückgesetzt werden, d.h. aus der URL entfernt werden. Dann nimmt er seinen Standardwert an:
<a n:href="Product:show $id, lang: null">klicken</a>
Interaktive Komponenten
Presenter haben ein eingebautes Komponentensystem. Komponenten sind separate, wiederverwendbare Einheiten, die wir in Presenter einfügen. Dies können Formulare, Datagrids, Menüs sein, eigentlich alles, was sinnvoll wiederverwendet werden kann.
Wie werden Komponenten in den Presenter eingefügt und anschließend verwendet? Das erfahren Sie im Kapitel Komponenten. Sie werden sogar herausfinden, was sie mit Hollywood gemeinsam haben.
Und wo kann ich Komponenten bekommen? Auf der Seite Componette finden Sie Open-Source-Komponenten sowie eine Reihe weiterer Add-ons für Nette, die von Freiwilligen aus der Community rund um das Framework hier platziert wurden.
Wir gehen in die Tiefe
Mit dem, was wir bisher in diesem Kapitel gezeigt haben, werden Sie wahrscheinlich vollkommen auskommen. Die folgenden Zeilen sind für diejenigen gedacht, die sich eingehender für Presenter interessieren und alles wissen möchten.
Validierung von Parametern
Die Werte der Anfrageparameter und persistenten
Parameter, die aus der URL empfangen werden, schreibt die Methode loadState()
in die Properties. Sie überprüft
auch, ob der bei der Property angegebene Datentyp übereinstimmt, andernfalls antwortet sie mit einem 404-Fehler und die Seite
wird nicht angezeigt.
Vertrauen Sie niemals blind Parametern, da sie vom Benutzer leicht in der URL überschrieben werden können. So überprüfen
wir beispielsweise, ob die Sprache $this->lang
zu den unterstützten gehört. Ein geeigneter Weg ist, die
erwähnte Methode loadState()
zu überschreiben:
class ProductPresenter extends Nette\Application\UI\Presenter
{
#[Persistent]
public string $lang;
public function loadState(array $params): void
{
parent::loadState($params); // hier wird $this->lang gesetzt
// es folgt die eigene Überprüfung des Wertes:
if (!in_array($this->lang, ['en', 'cs'])) {
$this->error();
}
}
}
Speichern und Wiederherstellen der Anfrage
Die Anfrage, die der Presenter bearbeitet, ist ein Objekt Nette\Application\Request und wird von der
Presenter-Methode getRequest()
zurückgegeben.
Die aktuelle Anfrage kann in der Session gespeichert oder daraus wiederhergestellt und vom Presenter erneut ausgeführt werden.
Dies ist nützlich, zum Beispiel in einer Situation, in der ein Benutzer ein Formular ausfüllt und seine Anmeldung abläuft. Um
die Daten nicht zu verlieren, speichern wir vor der Weiterleitung zur Anmeldeseite die aktuelle Anfrage mit
$reqId = $this->storeRequest()
in der Session. Diese Methode gibt ihren Identifikator in Form einer kurzen
Zeichenkette zurück, den wir als Parameter an den Anmelde-Presenter übergeben.
Nach der Anmeldung rufen wir die Methode $this->restoreRequest($reqId)
auf, die die Anfrage aus der Session
holt und dorthin weiterleitet (forward). Die Methode überprüft dabei, ob die Anfrage vom selben Benutzer erstellt wurde, der
sich jetzt angemeldet hat. Wenn sich ein anderer Benutzer angemeldet hat oder der Schlüssel ungültig ist, tut sie nichts und das
Programm läuft weiter.
Schauen Sie sich die Anleitung Wie man zu einer früheren Seite zurückkehrt an.
Kanonisierung
Presenter haben eine wirklich großartige Eigenschaft, die zu besserem SEO (Optimierung der Auffindbarkeit im Internet)
beiträgt. Sie verhindern automatisch das Vorhandensein von doppeltem Inhalt unter verschiedenen URLs. Wenn zu einem bestimmten
Ziel mehrere URL-Adressen führen, z.B. /index
und /index?page=1
, bestimmt das Framework eine davon als
primäre (kanonische) und leitet die anderen mit dem HTTP-Code 301 dorthin weiter. Dank dessen indizieren Suchmaschinen die
Seiten nicht zweimal und verwässern nicht deren Page Rank.
Dieser Prozess wird Kanonisierung genannt. Die kanonische URL ist diejenige, die vom Router generiert wird, in der Regel also die erste passende Route in der Sammlung.
Die Kanonisierung ist standardmäßig aktiviert und kann über $this->autoCanonicalize = false
deaktiviert
werden.
Bei einer AJAX- oder POST-Anfrage erfolgt keine Weiterleitung, da dies zu Datenverlust führen würde oder aus SEO-Sicht keinen Mehrwert hätte.
Sie können die Kanonisierung auch manuell mit der Methode canonicalize()
auslösen, der ähnlich wie der Methode
link()
der Presenter, die Aktion und die Parameter übergeben werden. Sie erstellt einen Link und vergleicht ihn mit
der aktuellen URL-Adresse. Wenn sie sich unterscheiden, wird auf den generierten Link weitergeleitet.
public function actionShow(int $id, ?string $slug = null): void
{
$realSlug = $this->facade->getSlugForId($id);
// leitet weiter, wenn $slug sich von $realSlug unterscheidet
$this->canonicalize('Product:show', [$id, $realSlug]);
}
Ereignisse
Neben den Methoden startup()
, beforeRender()
und shutdown()
, die als Teil des
Lebenszyklus des Presenters aufgerufen werden, können noch weitere Funktionen definiert werden, die automatisch aufgerufen werden
sollen. Der Presenter definiert sogenannte Ereignisse, deren
Handler Sie zu den Arrays $onStartup
, $onRender
und $onShutdown
hinzufügen.
class ArticlePresenter extends Nette\Application\UI\Presenter
{
public function __construct()
{
$this->onStartup[] = function () {
// ...
};
}
}
Die Handler im Array $onStartup
werden kurz vor der Methode startup()
aufgerufen,
$onRender
zwischen beforeRender()
und render<View>()
und schließlich
$onShutdown
kurz vor shutdown()
.
Antworten
Die Antwort, die ein Presenter zurückgibt, ist ein Objekt, das das Interface Nette\Application\Response implementiert. Es stehen eine Reihe von vorbereiteten Antworten zur Verfügung:
- Nette\Application\Responses\CallbackResponse – sendet einen Callback
- Nette\Application\Responses\FileResponse – sendet eine Datei
- Nette\Application\Responses\ForwardResponse – forward()
- Nette\Application\Responses\JsonResponse – sendet JSON
- Nette\Application\Responses\RedirectResponse – Weiterleitung
- Nette\Application\Responses\TextResponse – sendet Text
- Nette\Application\Responses\VoidResponse – leere Antwort
Antworten werden mit der Methode sendResponse()
gesendet:
use Nette\Application\Responses;
// Einfacher Text
$this->sendResponse(new Responses\TextResponse('Hello Nette!'));
// Sendet eine Datei
$this->sendResponse(new Responses\FileResponse(__DIR__ . '/invoice.pdf', 'Invoice13.pdf'));
// Die Antwort wird ein Callback sein
$callback = function (Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse) {
if ($httpResponse->getHeader('Content-Type') === 'text/html') {
echo '<h1>Hello</h1>';
}
};
$this->sendResponse(new Responses\CallbackResponse($callback));
Zugriffsbeschränkung mit #[Requires]
Das Attribut #[Requires]
bietet erweiterte Möglichkeiten zur Zugriffsbeschränkung für Presenter und deren
Methoden. Es kann verwendet werden, um HTTP-Methoden zu spezifizieren, eine AJAX-Anfrage zu erfordern, den Zugriff auf den
gleichen Ursprung (Same Origin) zu beschränken und den Zugriff nur über Forwarding zu erlauben. Das Attribut kann sowohl auf
Presenter-Klassen als auch auf einzelne Methoden action<Action>()
, render<View>()
,
handle<Signal>()
und createComponent<Name>()
angewendet werden.
Sie können folgende Beschränkungen festlegen:
- auf HTTP-Methoden:
#[Requires(methods: ['GET', 'POST'])]
- Erfordern einer AJAX-Anfrage:
#[Requires(ajax: true)]
- Zugriff nur vom gleichen Ursprung:
#[Requires(sameOrigin: true)]
- Zugriff nur über Forwarding:
#[Requires(forward: true)]
- Beschränkung auf bestimmte Aktionen:
#[Requires(actions: 'default')]
Details finden Sie in der Anleitung Verwendung des Requires-Attributs.
Überprüfung der HTTP-Methode
Presenter in Nette überprüfen automatisch die HTTP-Methode jeder eingehenden Anfrage. Der Grund für diese Überprüfung ist
hauptsächlich die Sicherheit. Standardmäßig sind die Methoden GET
, POST
, HEAD
,
PUT
, DELETE
, PATCH
erlaubt.
Wenn Sie zusätzlich beispielsweise die Methode OPTIONS
erlauben möchten, verwenden Sie dazu das Attribut
#[Requires]
(ab Nette Application v3.2):
#[Requires(methods: ['GET', 'POST', 'HEAD', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])]
class MyPresenter extends Nette\Application\UI\Presenter
{
}
In Version 3.1 erfolgt die Überprüfung in checkHttpMethod()
, die prüft, ob die in der Anfrage angegebene
Methode im Array $presenter->allowedMethods
enthalten ist. Fügen Sie die Methode wie folgt hinzu:
class MyPresenter extends Nette\Application\UI\Presenter
{
protected function checkHttpMethod(): void
{
$this->allowedMethods[] = 'OPTIONS';
parent::checkHttpMethod();
}
}
Es ist wichtig zu betonen, dass wenn Sie die Methode OPTIONS
zulassen, Sie diese anschließend auch entsprechend
in Ihrem Presenter behandeln müssen. Die Methode wird oft als sogenannter Preflight Request verwendet, den der Browser
automatisch vor der eigentlichen Anfrage sendet, wenn überprüft werden muss, ob die Anfrage gemäß der CORS (Cross-Origin
Resource Sharing) Richtlinie zulässig ist. Wenn Sie die Methode zulassen, aber keine korrekte Antwort implementieren, kann dies
zu Inkonsistenzen und potenziellen Sicherheitsproblemen führen.