„Damals hat eine einzige Datei gereicht …“
PHP, mit dem ich im Studium gearbeitet hatte, war wirklich bequem. In eine einzige index.php-Datei konnte man HTML-Tags schreiben, dazwischen <?php ?> öffnen und direkt den Code für Datenbankabfragen einfügen. Es gab keine klare Trennung zwischen Frontend und Backend. Wenn man eine Variable deklarierte, konnte man sie überall im HTML verwenden, und Fehler bei der Datenkommunikation waren praktisch kein Thema.
Aber als ich in der Praxis auf einen Stack mit Vue.js im Frontend und Spring Boot im Backend umstieg, begann die Hölle.
„Der Spring-Server läuft lokal doch eindeutig, die Vue-Oberfläche auch. Warum kommen die Daten dann nicht an?“
Die Konsole in den Chrome-Entwicklertools war komplett mit knallroten Fehlermeldungen überzogen.
Access to XMLHttpRequest at ... has been blocked by CORS policy
Was genau ist dieses „CORS“, das meine Daten blockiert? Und warum haben wir die bequeme Lösung mit nur einer Datei überhaupt aufgegeben, um Frontend und Backend absichtlich zu trennen?

Wer soll kochen? (SSR vs CSR)
Um diesen Wandel zu verstehen, muss man begreifen, wer das „Gericht“ namens Webseite, also HTML, eigentlich zubereitet. Genau darin liegt der Unterschied zwischen SSR (Server Side Rendering) und CSR (Client Side Rendering).
1. SSR: fertig gepackte Lunchbox (PHP, JSP)
- Prinzip: Der Server (die Küche) kocht Reis, Beilagen und Suppe komplett fertig und schickt alles hübsch angerichtet in einer Lunchbox (HTML).
- Client (Browser): muss nur noch den Deckel der Lunchbox öffnen und den Inhalt zeigen.
- Vorteile: Die erste Seite lädt schnell. Suchmaschinen (SEO) können den Inhalt gut lesen.
- Nachteile: Selbst wenn nur eine einzige Beilage ausgetauscht werden soll, muss die ganze Lunchbox neu geliefert werden. (Bildschirmflackern)
2. CSR: Meal-Kit-Lieferung (React, Vue)
- Prinzip: Der Server kocht nicht. Er schickt nur die Zutaten (JSON-Daten) und das Rezept (JavaScript).
- Client (Browser): brät und brutzelt die gelieferten Zutaten direkt auf meinem eigenen Rechner (im Browser) und baut daraus die Oberfläche.
- Vorteile: Weil sich gezielt einzelne Beilagen austauschen lassen, sind Seitenwechsel extrem flüssig (wie in einer App). Die Serverlast sinkt.
- Nachteile: Weil zuerst das Rezept (die JS-Dateien) heruntergeladen werden muss, ist das initiale Laden langsam.
[Tip] CSR und SPA sind nicht genau dasselbe
Die Begriffe werden oft durcheinander verwendet, streng genommen sind sie aber nicht identisch.
- CSR (Client Side Rendering): Das ist das „Wie“ (How). Gemeint ist die Methode, mit der der Browser die Oberfläche zeichnet.
- SPA (Single Page Application): Das ist das „Was“ (What). Gemeint ist eine Anwendung, die aus nur einer einzigen Seite besteht.
In der Praxis verwenden wir meist CSR, um eine SPA zu bauen. Anders gesagt: Weil wir mit nur einer Seite ohne ständiges Neuladen arbeiten wollen (SPA), entscheiden wir uns für eine Darstellungsmethode, bei der der Browser die nötigen Teile selbst nachzeichnet (CSR).
Der Grund, warum wir Vue.js oder React einsetzen, ist die User Experience. Damit sich eine Website flüssig wie eine Smartphone-App anfühlt, wurde das „Kochen“ von der Serverseite in den Browser verlagert.

CORS, der Wachmann gegen unerwünschte Besucher
Seit Frontend (Vue) und Backend (Spring) getrennt sind, haben wir praktisch zwei verschiedene Häuser.
- Haus des Frontends:
localhost:8080(Vue-Server) - Haus des Backends:
localhost:3000(Spring-Server)
Genau hier beginnt das Problem. Der Webbrowser folgt aus Sicherheitsgründen einer Grundregel: „Ressourcen aus einer anderen Origin sollte man nicht blind vertrauen.“ Das ist die SOP, also Same Origin Policy.
Man stelle sich vor: Ich bin bei Naver eingeloggt, und eine Seite eines Hackers schickt heimlich an den Naver-Server die Anfrage „Gib mir die persönlichen Daten dieses Nutzers.“ Würde der Browser das nicht blockieren, wären meine Informationen komplett ausgeliefert.
Deshalb blockiert der Browser standardmäßig Anfragen, sobald sich Origin, also Domain und Port, unterscheiden. Für die Entwicklung haben wir diese Ports aber absichtlich getrennt. Wir wollen nur unsere eigenen Daten nutzen, doch der Browser spielt den Wachmann und sagt: „Ihr Port stimmt nicht überein. Zutritt verboten.“ Genau das ist der Kern eines CORS-Fehlers, also Cross-Origin Resource Sharing.
[Code Verification] Einen Ausweis ausstellen
Die Lösung ist eigentlich einfach. Der Server, also das Backend, stellt dem Browser, also dem Wachmann, einen Ausweis aus: „Diese Person ist mein eingeladener Gast. Bitte hereinlassen.“
In Spring Boot lässt sich dieser Ausweis über eine einzige Konfigurationsdatei ausstellen.
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 1. Fuer alle API-Pfade
.allowedOrigins("http://localhost:8080") // 2. Anfragen von dieser Adresse zulassen
.allowedMethods("GET", "POST", "PUT", "DELETE") // 3. Solche Anfragen zulassen
.allowCredentials(true); // 4. Cookies und Authentifizierung sind erlaubt
}
}
Analyse:
allowedOrigins: Das ist das Wichtigste. Trägst du hier die Adresse des Frontend-Servers (localhost:8080) ein, drückt der Spring-Server dem Response-Header den StempelAccess-Control-Allow-Origin: http://localhost:8080auf und schickt ihn mit.- Der Browser prüft diesen Stempel, denkt sich „Ah, der Besitzer des Servers hat es erlaubt“ und reicht die Daten an das Frontend weiter.
Wichtig ist nur: Aus Bequemlichkeit sollte man nicht einfach mit allowedOrigins("*") alles freigeben. Das wäre so, als würde man die Haustür sperrangelweit offen lassen und ein Schild aufhängen: „Diebe willkommen.“
Praxisrat: Wann benutzt man was?
Ist CSR, also Vue oder React, damit automatisch immer die richtige Antwort? Nein. In der Praxis muss man abhängig vom Ziel entscheiden.
- Verwaltungsseiten (Admin), Dashboards:
- Empfehlung: CSR (Vue, React)
- Grund: Es gibt viel Interaktion mit Daten, und Sichtbarkeit in Suchmaschinen ist nicht nötig. Wichtig ist eine flotte, App-ähnliche Reaktionsfähigkeit.
- Nachrichtenseiten, Blogs, Startseiten von Onlineshops:
- Empfehlung: SSR (Next.js, Nuxt.js)
- Grund: Die Seiten müssen bei Google gut gefunden werden (SEO), und wenn Kunden die Seite aufrufen, soll statt eines weißen Bildschirms sofort der Inhalt erscheinen.
- Kleine private Projekte:
- Empfehlung: Thymeleaf (in Spring Boot integriertes SSR)
- Grund: Wenn du allein entwickelst, musst du dir nicht die Mühe machen, Front- und Backend zu trennen und CORS zu konfigurieren. Alles in einem Projekt zu entwickeln, wie zu PHP-Zeiten, bringt die höchste Produktivität.
Zum Schluss: Grenzen überwinden
Die alte PHP-Zeit als „Großfamilie unter einem Dach“ war bequem, wurde aber mit wachsender Komplexität immer schwerer zu handhaben. Die heutige Welt mit „zwei getrennten Haushalten“ aus Frontend und Backend ist wegen Kommunikationsthemen wie CORS zwar lästiger, erlaubt aber, dass sich jede Seite auf ihre eigene Aufgabe konzentriert.
Wenn du also das nächste Mal einen CORS-Fehler siehst, reagiere nicht nur genervt. Der Browser schikaniert dich nicht, sondern führt lediglich eine strenge Kontrolle durch, um dein Haus, also deinen Server, zu schützen.
Jetzt ist der Weg zwischen Frontend und Backend geöffnet. Daten können hin und her fließen. Aber wo werden diese Daten eigentlich auf dem Server gespeichert? Früher konnte ich einfach eine SQL-Abfrage absetzen und die Daten holen. In Spring scheint man wegen Dingen wie JPA und Entity plötzlich kein SQL mehr direkt schreiben zu dürfen.
Nächstes Mal sehen wir uns an, wie der „Lehrbuchstandard“ des Datenbankdesigns, die Normalisierung, in der Praxis zum Stolperstein werden kann und warum JPA so sehr versucht, SQL vor uns zu verstecken.


