Montag, 25 August 2025

Top 5 diese Woche

Ähnliche Tutorials

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="http://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>
Vorheriges Tutorial
Nächstes Tutorial

Hier etwas für dich dabei?