Moderne Websites setzen häufig auf AJAX (Asynchronous JavaScript and XML), um dynamische, reaktionsschnelle Benutzererlebnisse zu liefern, ohne die gesamte Seite neu zu laden. In TYPO3 können wir die Macht von AJAX nutzen, indem wir einen dedizierten typeNum-Endpunkt in TypoScript einrichten und asynchrone Aufrufe mit einem Extbase-Controller verarbeiten. Dieser Blog-Post führt Sie durch die einzelnen Schritte - von der Konfiguration von TypoScript für AJAX bis zur Rückgabe von JSON-Antworten und deren Verwendung in Ihrem Frontend-JavaScript. Kurz gesagt: Sie lernen, wie man AJAX in TYPO3 mit TypoScript und Extbase implementiert.
Was ist die kurze Antwort?
Für AJAX in TYPO3 stellen Sie einen Endpunkt bereit, der JSON liefert, und rufen ihn mit fetch() oder XMLHttpRequest auf. Nutzen Sie ein PAGE-Objekt mit eigener typeNum für einen schnellen Extbase-Endpunkt, eine PSR-15 Middleware für leichte Routen oder eine Extbase-Action mit jsonResponse(). Alle drei Wege funktionieren in TYPO3 v13.4 LTS und v14.
Das Wichtigste in Kürze
- Eine typeNum erzeugt einen eigenen Seitentyp. Mit disableAllHeaderCode = 1 enthält die Antwort kein Seiten-HTML.
- Setzen Sie config.no_cache = 1 nicht für den ganzen Seitentyp. Die TypoScript-Referenz empfiehlt, den Cache nur für das Objekt zu deaktivieren, das es braucht, zum Beispiel mit COA_INT.
- Extbase-Actions müssen ein ResponseInterface zurückgeben. $this->jsonResponse() ist die dokumentierte Abkürzung für JSON.
- Eine PSR-15 Middleware antwortet, bevor die Seite gerendert wird, bietet aber weder Extbase noch Fluid.
- Prüfen Sie den Zugriff im Endpunkt. Seit TYPO3 14.2 bietet Extbase die Attribute #[Authorize] und #[RateLimit].
Getestet mit / gültig für: TYPO3 v13.4 LTS und v14. Aktualisiert: November 2026
Welche AJAX-Methode passt zu meinem TYPO3-Projekt?
Wählen Sie typeNum, wenn Sie bereits ein Extbase-Plugin haben, eine Middleware für kleine eigenständige Endpunkte und eine Extbase-JSON-Action, wenn die Logik in einen Controller mit Repositories gehört.
| Methode | Funktioniert in | Am besten für | Einschränkung |
|---|---|---|---|
| PAGE mit typeNum (TypoScript) | v13.4 LTS und v14 | Ein vorhandenes Extbase-Plugin als JSON-Endpunkt nutzen | Läuft durch das Frontend-Rendering. Caching pro Objekt (COA_INT) steuern, statt config.no_cache zu setzen. |
| PSR-15 Middleware | v13.4 LTS und v14 | Kleine, schnelle Endpunkte wie Statusabfragen | Kein Extbase, kein Fluid. Routing-Prüfung und Eingabevalidierung machen Sie selbst. |
| Extbase-Action mit jsonResponse() | v13.4 LTS und v14 | Geschäftslogik mit Repositories und Modellen | Die Action muss ein ResponseInterface zurückgeben. |
Quellen: PAGE-Beispiele, Middlewares und ActionController in der offiziellen TYPO3-Dokumentation.
Warum AJAX in TYPO3 verwenden?
- Verbesserte Benutzerfreundlichkeit: Sie müssen nicht die gesamte Seite neu laden, sondern nur bestimmte Komponenten aktualisieren.
- Bessere Leistung: Holen Sie nur die erforderlichen Daten ab und reduzieren Sie so die Serverlast und die Ladezeiten der Seite.
- Modular und wartungsfreundlich: Halten Sie Ihre Logik übersichtlich, indem Sie AJAX-Aufrufe in einem eigenen Controller/Aktion isolieren.
1. Erstellen eines AJAX-Endpunkts mit TypoScript
Der erste Schritt besteht darin, ein spezielles PAGE-Objekt in TypoScript zu erstellen und eine eindeutige typeNum zuzuweisen, um Ihre AJAX-Anfragen zu bearbeiten.
ajax_page = PAGE
ajax_page {
typeNum = 123456 # Unique number for the AJAX call
config {
disableAllHeaderCode = 1
additionalHeaders = Content-type:application/json
xhtml_cleaning = 0
admPanel = 0
debug = 0
no_cache = 1
}
10 = USER
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = YourExtension
pluginName = YourPlugin
vendorName = YourVendor
controller = YourController
action = yourAjaxAction
}
} Wichtige Punkte
1. typeNum: Weisen Sie eine eindeutige Ganzzahl zu, um diese AJAX-Anfrage von anderen TYPO3-Seitentypen zu unterscheiden.
2. disableAllHeaderCode: Stellt sicher, dass keine zusätzlichen HTML-Header enthalten sind - ideal für JSON-Antworten.
3. USER: Leitet die Anfrage an Ihren Extbase-Controller/die Aktion weiter, der/die die Anfrage verarbeitet und Daten zurückgibt.
2. Implementierung des Extbase-Controllers
Als nächstes erstellen (oder aktualisieren) Sie eine Extbase-Controller-Aktion speziell für die Bearbeitung der AJAX-Anfrage. Durch die Nutzung von JsonView kann TYPO3 automatisch eine JSON-Antwort zurückgeben, die leicht in Ihrem JavaScript zu verwenden ist.
namespace Vendor\YourExtension\Controller;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\View\JsonView;
class YourController extends ActionController
{
protected $defaultViewObjectName = JsonView::class; // Return JSON response
public function yourAjaxAction()
{
// Your business logic here
$data = [
'message' => 'Hello, this is a response from the AJAX call',
'status' => true,
];
// Assign data to the view for JSON output
$this->view->assign('value', $data);
}
} Wichtige Punkte
1. JsonView: Konvertiert das zugewiesene PHP-Array/Objekt automatisch in eine JSON-Ausgabe.
2. Geschäftslogik: Führen Sie hier alle serverseitigen Operationen durch, z. B. Datenbankabfragen, Validierungen oder benutzerdefinierte Geschäftsregeln.
3. Auslösen der AJAX-Anfrage aus JavaScript
Schließlich benötigen Sie eine Möglichkeit, den neu erstellten AJAX-Endpunkt von Ihrem Frontend aus aufzurufen. Im Folgenden finden Sie ein Beispiel für die Verwendung von einfachem JavaScript (XMLHttpRequest); Sie können jedoch auch fetch() oder $.ajax() von jQuery verwenden, wenn Sie dies wünschen.
// Create an XMLHttpRequest object
var xhr = new XMLHttpRequest();
// Define the URL (with the typeNum parameter)
var url = "/?type=123456"; // Replace '123456' with your actual typeNum
// Open the request
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// On successful response
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
// Parse JSON response
var response = JSON.parse(xhr.responseText);
console.log(response); // Handle the server response data
} else {
console.error('Request failed. Status: ' + xhr.status);
}
};
// On request error
xhr.onerror = function() {
console.error('AJAX request failed');
};
// Data to send
var data = "param1=value1¶m2=value2";
// Send the request
xhr.send(data); Wichtige Punkte
1. xhr.open("POST", url, true): Legt die HTTP-Methode (GET oder POST), die Ziel-URL und das Asynchronitätsflag fest.
2. xhr.setRequestHeader(): (Optional) Verwenden Sie dies, um Inhaltstypen oder benutzerdefinierte Kopfzeilen festzulegen.
3. Antwort-Verarbeitung: JSON-Antworten können mit JSON.parse() geparst werden, um den Zugriff zu erleichtern.
Kostenlose TYPO3-Leitfäden
Lesen Sie unsere kostenlosen TYPO3-Leitfäden für Entwickler und Integratoren, direkt nutzbar im nächsten Projekt.
4. (Optional) Konfigurieren Sie saubere URLs mit Routing
Für TYPO3 v9 und höher können Sie Ihren AJAX-Endpunkt benutzerfreundlicher gestalten, indem Sie Routenerweiterungen einrichten. Definieren Sie in Ihrer config.yaml eine Route für Ihre typeNum:
routeEnhancers:
AjaxType:
type: Simple
defaultController: 'Vendor\YourExtension\Controller\YourController::yourAjaxAction'
requirements:
type: '\d+'
default: '' So können Sie hübsche URLs erstellen, anstatt /?type=123456 zu verwenden. Passen Sie Ihre JavaScript-Anfrage entsprechend an.
Beispiel aus der Praxis
Ein typisches Szenario ist die Auflistung von Datensätzen aus einer Extension, wie sie z.B. unser TYPO3 Extension Helpdesk verwendet:
listAction = PAGE
listAction {
typeNum = 741852
config {
disableAllHeaderCode = 1
additionalHeaders = Content-type:application/json
xhtml_cleaning = 0
admPanel = 0
}
10 = USER
10 < styles.content.get
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = NsHelpdesk
pluginName = Helpdesk
vendorName = NITSAN
controller = Tickets
switchableControllerActions {
Tickets {
1 = list
}
}
# Carry plugin settings along in the AJAX call
stdWrap.trim = 1
select {
where = list_type = "nshelpdesk_helpdesk"
}
renderObj < tt_content.list.20.nshelpdesk_helpdesk
}
} Durch den Verweis auf /?type=741852 (oder Ihre ausgefallene Route, falls konfiguriert) können Sie asynchron eine Liste von Support-Tickets von Helpdesk abrufen und sie in Ihrem JavaScript-Code bearbeiten.
Wie gebe ich JSON aus einer Middleware oder Extbase-Action zurück?
Beide Alternativen umgehen den Seitentyp mit typeNum. Eine PSR-15 Middleware antwortet früh im Request, eine Extbase-Action liefert ihr JSON mit jsonResponse().
Option A: PSR-15 Middleware
TYPO3 setzt für eingehende Requests PSR-15 Middlewares ein. Dieses Beispiel aus der TYPO3-Dokumentation liefert JSON für den Pfad /check:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Middleware;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class StatusCheckMiddleware implements MiddlewareInterface
{
public function __construct(
private readonly ResponseFactoryInterface $responseFactory,
) {}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if ($request->getRequestTarget() === '/check') {
$response = $this->responseFactory->createResponse()
->withHeader('Content-Type', 'application/json; charset=utf-8');
$response->getBody()->write(json_encode(['status' => 'ok']));
return $response;
}
return $handler->handle($request);
}
}
Registrieren Sie sie im Frontend-Stack in EXT:my_extension/Configuration/RequestMiddlewares.php:
<?php
return [
'frontend' => [
'my-extension/status-check' => [
'target' => \MyVendor\MyExtension\Middleware\StatusCheckMiddleware::class,
],
],
];
Option B: Extbase-Action mit jsonResponse()
Extbase-Controller-Actions müssen ein ResponseInterface zurückgeben, wie die Dokumentation zum ActionController beschreibt. Für JSON geben Sie die Abkürzung $this->jsonResponse() zurück, statt den JsonView aus dem Beispiel oben zu verwenden:
public function yourAjaxAction(): ResponseInterface
{
$data = ['message' => 'Hallo aus dem AJAX-Aufruf', 'status' => true];
return $this->jsonResponse(json_encode($data));
}
Aktualisierung zum TypoScript-Beispiel
Seit TYPO3 12.3 können Sie ein Extbase-Plugin mit dem Content-Objekt EXTBASEPLUGIN registrieren, statt USER mit Bootstrap->run zu verwenden. Der alte Weg funktioniert weiterhin, wie der Changelog festhält:
ajax_page.10 = EXTBASEPLUGIN
ajax_page.10.extensionName = YourExtension
ajax_page.10.pluginName = YourPlugin
Suchen Sie fertige Funktionen statt Eigenentwicklung? Sehen Sie sich unsere TYPO3 Extensions an. Weiterführend: benutzerdefinierte TYPO3 Middleware erstellen und Switchable Controller Actions in Extbase migrieren.
Wie sichere und cache ich einen AJAX-Endpunkt?
Behandeln Sie jeden Endpunkt wie eine öffentliche URL: Eingaben validieren, Aufrufer prüfen und nur Antworten cachen, die sich gefahrlos teilen lassen.
- Nutzen Sie GET für lesende Requests und POST für Requests, die Daten ändern, und validieren Sie jeden Parameter auf dem Server.
- Seit TYPO3 14.2 kann #[Authorize] für eine Extbase-Action einen Frontend-Login oder Benutzergruppen verlangen.
- Seit TYPO3 14.2 begrenzt #[RateLimit] die Requests pro IP-Adresse. Es funktioniert nur für ungecachte Extbase-Actions.
- Statt config.no_cache = 1 kapseln Sie nur das dynamische Objekt in COA_INT, wie die TypoScript-Referenz zeigt.
Häufige Fehler und Fehlersuche
- HTML um das JSON: Setzen Sie config.disableAllHeaderCode = 1 am PAGE-Objekt.
- Browser behandelt die Antwort als HTML: Senden Sie den Header Content-type:application/json oder nutzen Sie in Extbase jsonResponse().
- Endpunkt liefert die normale Seite: Prüfen Sie, ob die typeNum eindeutig und das TypoScript geladen ist.
- Alte Daten nach einer Änderung: Die Antwort wurde gecacht. Leeren Sie den Cache und machen Sie das dynamische Objekt ungecacht.
- Action bricht mit Fehler ab: Stellen Sie sicher, dass die Action ein ResponseInterface zurückgibt.
Weitere Fragen
Was ist der Unterschied zwischen typeNum und Middleware?
Eine typeNum ist ein Seitentyp, den TYPO3 über das Frontend rendert, sodass Plugins und TypoScript wiederverwendbar sind. Eine Middleware läuft früher im Request und liefert direkt eine Antwort. Sie ist leichter, doch Routing und Validierung bauen Sie selbst.
Brauche ich Extbase für AJAX in TYPO3?
Nein. Eine PSR-15 Middleware kann JSON ohne Extbase liefern, wie die TYPO3-Dokumentation zeigt. Extbase lohnt sich, wenn Sie Repositories, Modelle und Validierung in einem Controller nutzen möchten.
Kann ich fetch() statt XMLHttpRequest verwenden?
Ja. fetch() ist eine Browser-API und funktioniert mit jedem TYPO3-Endpunkt, der JSON liefert. Rufen Sie dieselbe URL auf, zum Beispiel /?type=123456, und lesen Sie die Antwort mit response.json().
Ist config.no_cache = 1 für AJAX nötig?
Nein. Viele Tutorials setzen es, doch die TypoScript-Referenz rät, den Cache nur für das Objekt zu deaktivieren, das dynamisch bleiben muss, zum Beispiel mit COA_INT, und alle anderen Caches unangetastet zu lassen.
Upgrade-Leitfaden für TYPO3
Planen Sie den Wechsel auf eine aktuelle TYPO3-Version? Folgen Sie unserem Upgrade-Leitfaden Schritt für Schritt.
Schlussfolgerung
Die Implementierung von AJAX in TYPO3 mit TypoScripts typeNum und Extbase ist einfach und leistungsstark. Indem Sie Ihre AJAX-Logik in eine dedizierte Controller-Aktion auslagern, halten Sie das System sauber, modular und einfach zu pflegen. Egal, ob Sie kleine Komponenten aktualisieren oder eine komplette Single-Page-Anwendung erstellen, die Flexibilität von TYPO3 macht alles möglich.
Haben Sie Fragen oder besondere Anwendungsfälle? Schreiben Sie sie in die Kommentare oder wenden Sie sich an die T3Planet Community. Wir würden uns freuen zu hören, wie Sie AJAX in Ihren TYPO3 Projekten einsetzen!
Viel Spaß beim AJAX-Einsatz mit TYPO3!