Mittwoch, 21 Januar 2026

Diese Woche am beliebtesten

Vertiefendes Material

Planung mit Ajax

Dieses Tutorial richtet sich an Entwickler, die AJAX praxisnah lernen wollen. Am Ende wirst du ein funktionierendes Highscore-System haben, das Benutzer dynamisch einträgt, anzeigt und die Datenbank verwendet, ohne die Seite neu zu laden.


1. Projektidee und Vorbereitung

Wir wollen ein Highscore-Board für ein Spiel bauen. Funktionen:

  • Spieler kann seinen Namen und Punkte eintragen.
  • Highscores werden dynamisch angezeigt.
  • Es gibt eine Datenbank zur Speicherung.
  • Alles passiert asynchron, ohne Seitenreload.
  • Benutzerfreundliches Design (Buttons, Feedback, Ladeindikatoren).

Vorbereitung:

  • Webserver mit PHP (z. B. XAMPP, MAMP, LAMP)
  • Datenbank (MySQL oder SQLite)
  • Browser mit Developer Tools (Console & Network)

2. Datenbankdesign

Bevor wir AJAX einsetzen, müssen wir verstehen, welche Daten wir speichern:

  • Tabelle: highscores
  • Spalten:
    • id (Primärschlüssel)
    • username (Spielername)
    • score (Punkte)
    • timestamp (Zeitpunkt des Eintrags)

Warum?

  • Wir brauchen einen Ort, um Daten zu persistieren.
  • Timestamp hilft bei Sortierung und Verwaltung.

Best Practice: Index auf score setzen für schnelle Sortierung.


3. HTML-Struktur

Das Frontend muss Elemente haben, die wir dynamisch aktualisieren:

  • Eingabefelder für Name und Punkte
  • Button zum Absenden
  • Bereich für Highscore-Liste
  • Ladeanzeige oder Feedback

Wichtig:

  • Jeder Bereich sollte eine eindeutige ID oder Klasse haben.
  • So kann JavaScript gezielt Inhalte aktualisieren.

Konzept: HTML dient nur als Container. Die Logik wird über AJAX gesteuert.


4. AJAX-Konzept verstehen

AJAX ermöglicht asynchrone Anfragen:

  • Request: Browser fragt den Server nach Daten.
  • Response: Server liefert Daten zurück (JSON ist Standard).
  • Update: JavaScript aktualisiert die Seite dynamisch.

Flow:

  1. Nutzer klickt auf „Highscore speichern“.
  2. JS sammelt Daten (Name, Punkte).
  3. AJAX-Request wird an PHP-Skript geschickt.
  4. PHP speichert Daten in Datenbank.
  5. PHP sendet Response (Erfolg, Fehler).
  6. JS zeigt Rückmeldung und lädt aktualisierte Highscore-Liste.

5. Server-Seite (PHP)

Der Server muss Requests entgegennehmen und verarbeiten:

  • Eingaben validieren (Sicherheit)
  • Highscore speichern
  • Highscore abrufen
  • Fehler sauber zurückgeben

Best Practices:

  • Prepared Statements gegen SQL-Injection.
  • Sanitizing: HTML/JS-Sonderzeichen entfernen.
  • Response immer JSON: Einfaches Parsen im Frontend.

6. Frontend-Logik (JavaScript)

Aufgaben:

  • Daten sammeln und senden
  • AJAX-Request erstellen
  • Response verarbeiten
  • UI aktualisieren (Highscore-Liste, Feedback)

Wichtige Konzepte:

  • EventListener für Button-Klick
  • Fetch API oder XMLHttpRequest
  • Promise Handling für asynchrone Abläufe
  • Error Handling: Netzwerkprobleme, Serverfehler

Tipp: Ladeanzeige zeigen, solange Server antwortet, sonst wirkt die Seite „statisch“.


7. Dynamische Highscore-Liste

Highscores müssen nach jedem Eintrag aktualisiert werden, ohne Reload:

  1. AJAX holt aktuelle Top10-Scores vom Server.
  2. JS leert die bestehende Liste.
  3. JS baut neue Listenelemente und fügt sie ein.

Best Practices:

  • Liste in <ul> oder <table> einfügen.
  • Bei vielen Einträgen Pagination oder Limit einbauen.
  • Optional: Animation beim Aktualisieren.

8. Sicherheitsaspekte

AJAX allein macht das Frontend nicht sicher:

  • Input-Validation: Immer serverseitig prüfen.
  • Rate-Limiting: Spam verhindern, z. B. nur 1 Eintrag pro 10 Sekunden pro IP.
  • Captcha: Optional, um Bots zu blockieren.
  • Prepared Statements: Verhindern SQL-Injection.

Frontend-Sicherheiten können umgangen werden, Server ist die letzte Schutzebene.


9. Erweiterungsmöglichkeiten

  • E-Mail Bestätigung: Spielername + Score nur nach E-Mail-Verifikation speichern.
  • Benutzerkonten: Highscore pro Account speichern.
  • Live-Update: WebSocket oder regelmäßiges AJAX-Refresh.
  • PWA: Mobile Installation, offline Anzeige der Highscores.

10. Fazit und Zusammenfassung

Mit AJAX:

  • Webseiten fühlen sich flüssig an.
  • Nutzerinteraktionen erfolgen sofort.
  • Datenbankinteraktionen sind asynchron, was die UX verbessert.
  • Konzepte wie EventListener, Fetch API und JSON sind zentral.

Wer AJAX versteht, kann klassische Webseiten in interaktive Web-Apps verwandeln.
Der nächste Schritt ist, die Kombination aus AJAX, PHP und Datenbank zu meistern und eigene dynamische Webprojekte zu bauen.

Das sehe dann so aus:

<?php
// Highscore Demo
session_start();

// SQLite-Datenbank erstellen oder verbinden
$db = new PDO('sqlite:'.__DIR__.'/highscores.db');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec("CREATE TABLE IF NOT EXISTS highscores (
    id INTEGER PRIMARY KEY,
    username TEXT,
    score INTEGER,
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)");

// Highscore speichern
if(isset($_POST['action']) && $_POST['action'] === 'save_score'){
    $username = htmlspecialchars($_POST['username']);
    $score = intval($_POST['score']);
    if($username && $score>=0){
        $stmt = $db->prepare("INSERT INTO highscores (username, score) VALUES (?, ?)");
        $stmt->execute([$username, $score]);
        echo json_encode(['success'=>true]);
    } else {
        echo json_encode(['success'=>false,'error'=>'Ungültige Daten']);
    }
    exit;
}

// Highscores abrufen
if(isset($_GET['action']) && $_GET['action'] === 'get_scores'){
    $stmt = $db->query("SELECT username, score FROM highscores ORDER BY score DESC LIMIT 10");
    $scores = $stmt->fetchAll(PDO::FETCH_ASSOC);
    echo json_encode($scores);
    exit;
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Highscore AJAX Demo</title>
<style>
body{margin:0;font-family:sans-serif;background:#111;color:#eee;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;min-height:100vh;}
header{padding:20px;text-align:center;font-size:2em;color:#ffcc00;}
#game-area{margin:20px auto;text-align:center;}
input, button{padding:8px 12px;margin:5px;border:none;border-radius:4px;}
input{width:200px;}
button{background:#ffcc00;color:#111;font-weight:bold;cursor:pointer;}
#feedback{margin-top:10px;color:#ff6666;}
#highscores{margin-top:20px;width:300px;text-align:left;}
#highscores ul{list-style:none;padding:0;}
#highscores li{padding:5px;border-bottom:1px solid #333;}
footer{margin-top:auto;padding:10px;color:#888;text-align:center;}
</style>
</head>
<body>
<header>Highscore AJAX Demo</header>

<div id="game-area">
    <input type="text" id="username" placeholder="Dein Name">
    <input type="number" id="score" placeholder="Punkte">
    <button id="saveScore">Highscore speichern</button>
    <div id="feedback"></div>
</div>

<div id="highscores">
<h3>Top 10 Highscores</h3>
<ul id="scoreList"></ul>
</div>

<footer>© <?=date('Y')?> <a href="https://www.dreamcodes.net" target="_blank">Dreamcodes</a> — Highscore Demo</footer>

<script>
// Funktion zum Laden der Highscores
function loadScores(){
    fetch('?action=get_scores')
    .then(response => response.json())
    .then(data => {
        const list = document.getElementById('scoreList');
        list.innerHTML = '';
        data.forEach(s => {
            const li = document.createElement('li');
            li.textContent = `${s.username}: ${s.score}`;
            list.appendChild(li);
        });
    });
}

// Highscore speichern
document.getElementById('saveScore').addEventListener('click', ()=>{
    const username = document.getElementById('username').value.trim();
    const score = parseInt(document.getElementById('score').value.trim());
    const feedback = document.getElementById('feedback');

    if(!username || isNaN(score)){
        feedback.textContent = 'Bitte Name und Punkte korrekt eingeben!';
        return;
    }

    feedback.textContent = 'Speichern...';
    fetch('',{
        method:'POST',
        headers:{'Content-Type':'application/x-www-form-urlencoded'},
        body:`action=save_score&username=${encodeURIComponent(username)}&score=${score}`
    })
    .then(r=>r.json())
    .then(res=>{
        if(res.success){
            feedback.style.color = '#00ff00';
            feedback.textContent = 'Highscore gespeichert!';
            document.getElementById('username').value = '';
            document.getElementById('score').value = '';
            loadScores();
        } else {
            feedback.style.color = '#ff6666';
            feedback.textContent = res.error || 'Fehler beim Speichern';
        }
    })
    .catch(()=>feedback.textContent='Serverfehler');
});

// Initial Highscores laden
loadScores();
</script>
</body>
</html>
Dreamcodes Redaktion
Dreamcodes Redaktion
Qualität als Standard. Verantwortung als Prinzip. Jede Ressource auf Dreamcodes basiert auf geprüften Best Practices und fundierter Praxiserfahrung. Unser Anspruch ist ein belastbares Fundament statt experimenteller Lösungen. Die Integration und Absicherung der Inhalte liegt in Ihrem Ermessen. Wir liefern die fachliche Basis, die Verantwortung für den produktiven Einsatz verbleibt bei Ihnen.
Vorheriges Tutorial
Nächstes Tutorial

Vielleicht einen Blick WERT?