Logo
Lena Peters
2 Std vor
Die meisten Einsteiger tippen any, wenn ein Typ nicht sofort passt. Dabei schaltet genau das die Prüfung ab, die TypeScript leistet.

TypeScript erweitert JavaScript um statische Typen; der Compiler prüft die Typen und erzeugt daraus normales JavaScript. Wer ankommende Daten als any deklariert, verschenkt diesen Schutz vollständig.

🌐 Externe Daten aus dem Netz sind zur Laufzeit nicht typisiert. JSON ist das verbreitete Datenformat von Web-APIs: Objekte mit Schlüssel-Wert-Paaren, Listen, Zeichenketten, Zahlen sowie true, false und null. Das Backend eines anderen Anbieters kann jederzeit ein Feld weglassen, null statt einer Zahl liefern oder ein Objekt statt einer Liste schicken. Der Typ im eigenen Code weiß davon nichts.

🧩 any schaltet den Typprüfungspfad ab, unknown erzwingt ihn. Der Typ any akzeptiert jede Operation, auch solche, die zur Laufzeit scheitern. Der Typ unknown ist die typsichere Variante: Der Wert darf darin landen, aber jede Operation erfordert vorher eine Typprüfung (Narrowing, das schrittweise Einengen des Typs), sonst kompiliert der Code nicht.

🔒 Erst prüfen, dann typisieren – Schritt für Schritt. JSON.parse liefert in TypeScript any, das Ergebnis einer fetch-Abfrage muss ebenfalls selbst geprüft werden. Bewährt hat sich: Das Ergebnis sofort unknown zuzuweisen. Dann mit typeof primitive Werte prüfen, mit Array.isArray Listen erkennen und einzelne Felder gegen erwartete Typen vergleichen. Erst danach den Wert einem echten Typ wie User zuweisen.

any heißt nicht „irgendein Typ“, sondern „keine Prüfung mehr“. unknown heißt nicht „unbekannt und ungeeignet“, sondern „unbekannt und kontrolliert“.

📌 unknown statt any · Typprüfung mit Narrowing · JSON.parse liefert any

📚 Webentwicklung von Grund auf · Tag 6 von 30
#typescript #webdev #javascript
Lena Peters
14 Std vor
Ein Kommentarfeld sieht aus wie ein Feld für Text. Für den Browser ist jede Ausgabe aber erst einmal Teil der Seite, den er liest, nicht reiner Text.

Genau hier werden Eingabe und Ausgabe verwechselt. Viele prüfen, was hereinkommt, und halten die Seite dann für sicher. Ob Cross-Site Scripting (XSS) entsteht, entscheidet sich aber erst bei der Ausgabe.

Eingabefilterung prüft Daten, bevor der Server sie annimmt. Sie blockt etwa HTML-Zeichen im Kommentarfeld oder lehnt verdächtige Werte ab. Das Problem: Ein Filter kann nie alle Fälle kennen. Gibt jemand statt eines Kommentars ein script-Element mit JavaScript ein, entscheidet nicht der Filter, sondern erst die Ausgabe, ob es läuft.

Ausgabekodierung, auch Escaping genannt, greift dort, wo der Schaden entsteht. Sie ersetzt Zeichen mit Sonderbedeutung durch ungefährliche Kürzel. So wird < zu &lt;, und der Browser zeigt spitze Klammern als Text an, statt sie als Tag zu lesen.

Filterung schätzt die Eingabe ein, Kodierung entschärft die Ausgabe. Weil dieselbe Eingabe in HTML-Text, Attribut, URL oder JavaScript-String je eigene Kodierungsregeln braucht, schützt nur kontextgerechtes Escaping an jedem Ausgabeort.

„Faustregel:" Eingaben validieren, um fehlerhafte Daten abzuweisen; für Sicherheit aber jede Ausgabe im passenden Kontext kodieren. Eine Content Security Policy, die vorgibt, von wo Skripte geladen dürfen, ergänzt das als zweite Verteidigungslinie.

XSS heißt nicht, dass jemand den Server knackt, sondern dass fremdes Skript im Browser der Opfer läuft – etwa mit deren Sitzungs-Cookies. Geschlossen wird die Lücke durch Kodierung am Ausgabeort, nicht durchs Filtern allein.

📌 Eingabe prüfen · Ausgabe kodieren · Kontext beachten

📚 Webentwicklung von Grund auf · Tag 5 von 30
#WebSecurity #webdev #javascript
Lena Peters
1 Tag vor
TypeScript kennt den Typ einer Variable oft besser, als die Deklaration vermuten lässt. Nach einer einzigen Prüfung im Code verschwinden Fehler, die vorher rot unterstrichen waren.

Einsteiger begegnen dem bei Union-Typen, also Typangaben wie string | number, die mehrere Typen erlauben. Wer sie nicht kennt, wundert sich, warum der Zugriff auf length verboten ist. Der Compiler weiß ja nicht, welcher der beiden Typen gerade drinsteckt.

Das Einengen dieses Typs heißt Narrowing: Der Compiler verengt die Typangabe durch Prüfungen, die der Code ohnehin ausführt. Er analysiert den Kontrollfluss; nach einer bestandenen Prüfung gilt im Block nur der eingegrenzte Typ, im else-Zweig der Rest.

Typisch ist der typeof-Operator, der zur Laufzeit eine Zeichenkette wie "string" liefert. Beispiel: eine Funktion laenge mit Parameter value vom Typ string | number. Sie prüft zuerst mit if, ob typeof value den Wert "string" ergibt; nur dann liefert sie value.length, sonst value.toString().length. Ohne die Prüfung wäre der Zugriff auf length ein Fehler, weil number diese Eigenschaft nicht hat. instanceof prüft, ob ein Objekt von einer Klasse abstammt, und gibt deren Methoden frei. Literalvergleiche wie if (value === "admin") grenzen auf genau diesen Wert ein, besonders bei diskriminierten Unions mit einem Feld wie kind.

Narrowing wird gern mit Validierung verwechselt, also der echten Prüfung ankommender Daten. JSON.parse gibt den Typ any zurück; eine Behauptung wie as User unterdrückt nur die Compilerwarnung. Typen existieren nur zur Übersetzungszeit, im erzeugten JavaScript ist nichts davon übrig.

Narrowing ist keine Prüfung, sondern ein Schluss aus Prüfungen. Es ersetzt die Validierung externer Daten nicht, es setzt sie voraus.

📌 typeof · instanceof · Kontrollfluss

📚 Webentwicklung von Grund auf · Tag 5 von 30
#typescript #javascript #webdev
Lena Peters
1 Tag vor
TypeScript verspricht Sicherheit, doch nach dem Übersetzen ist davon nichts mehr da. Wer das nicht weiß, vertraut Daten, die nie geprüft wurden.

TypeScript übersetzt den Code nach JavaScript, und dabei verschwinden alle Typangaben. Der Vorgang heißt Kompilieren, also das Übersetzen des Quelltexts in ausführbaren Code, und er läuft bei jedem Build.

Zuerst schreibt man Typen wie const user: User in den Code. Eine Typangabe ist eine Zusicherung an den Compiler, also das Übersetzungsprogramm: Sie sagt „vertrau mir“, statt einen Wert zu prüfen. Der Compiler sieht nur die Deklaration, nie die echten Daten.

Dann kommt Daten von außen: von einer Web-API über das Netzwerk, aus einer Datei oder von Nutzern. JSON ist dabei das verbreitete Format, mit Schlüssel-Wert-Paaren, Listen, Zeichenketten, Zahlen sowie true, false und null. Zur Laufzeit, also während das Programm läuft, weiß der Code nichts mehr von Typen.

Danach verwandelt JSON.parse die ankommende Zeichenkette in ein Objekt. In TypeScript gibt die Methode den Typ any zurück, und any schaltet die Typprüfung für diesen Wert ab. Schreibt man as User dazu, unterdrückt das nur eine Compilerwarnung: Die Daten bleiben ungeschützt.

Zuletzt prüft man selbst, bevor man einen Typ vertraut: Ist der Wert ein Objekt, existieren die erwarteten Felder, passen ihre Typen? Ein Typtest wie typeof x === "string" sichert das Ergebnis ab. Besser noch: eine kleine Prüffunktion, die unknown entgegennimmt und erst nach bestandener Prüfung einen konkreten Typ zurückgibt.

Eine Typangabe heißt nicht „geprüft“, sondern „behauptet“. Was zur Laufzeit ankommt, muss zur Laufzeit geprüft werden.

📌 Typen zur Übersetzungszeit · JSON.parse gibt any · unknown plus Prüffunktion

📚 Webentwicklung von Grund auf · Tag 5 von 30
#typescript #javascript #webdev
Lena Peters
1 Tag vor
JavaScript läuft im Browser – und TypeScript landet dort ebenfalls, aber nur als übersetztes Ergebnis. Der Unterschied liegt darin, was vor dem Start geprüft wird.

Die Verwechslung ist naheliegend: TypeScript sieht fast aus wie JavaScript und erzeugt am Ende auch genau das. Doch TypeScript ist eine Sprache mit statischen Typen, das heißt, der Compiler prüft schon vor dem Start, welche Art von Wert in jeder Variable steckt. JavaScript dagegen entscheidet Typen erst zur Laufzeit, also während das Programm läuft.

JavaScript ist die Skriptsprache, die das Verhalten einer Seite im Browser steuert. Der Browser führt den Code unmittelbar aus, ohne dass vorher ein Compiler die Typen prüft. Ein Beispiel: „5“ + 5 ergibt den String „55“, weil die Zeichenkette den Typ der Verknüpfung bestimmt. Der Fehler fällt erst beim Nutzer auf.

TypeScript ist JavaScript, erweitert um Typangaben wie string für Zeichenketten, number für Zahlen und boolean für Wahrheitswerte. Der Compiler prüft alle Typen und erzeugt daraus normales JavaScript. Eine Signatur wie function alter(pruefe: string): number sagt beim Lesen, was hineingehört und was herauskommt; ein Interface namens Nutzer mit den Feldern name und alter meldet fehlende Felder vor dem Start.

TypeScript wirft die Typangaben beim Übersetzen vollständig weg. In der ausgegebenen Datei stehen keine Typen mehr, und der Browser führt gewöhnliches JavaScript aus.

Faustregel: In TypeScript entwickeln, um Fehler früh im Editor zu sehen – aber nie erwarten, dass der Browser dadurch geschützt wird. Typen sind ein Werkzeug der Entwicklungszeit, kein Schutz zur Laufzeit.

TypeScript macht also nicht den Code im Browser sicherer, sondern fängt Typfehler vor dem Start ab, statt dass sie beim Nutzer auftreten. Wer das trennt, nutzt beide Sprachen richtig.

📌 Statische Typen · Compiler · Interface

📚 Webentwicklung von Grund auf · Tag 5 von 30
#typescript #javascript #webdev
Lena Peters
1 Tag vor
npm funktioniert wie eine Einkaufsliste, die der Lieferdienst selbst abruft. Dabei schreibt niemand die Bausteine selbst, die das Projekt braucht.

Ein Bauherr plant ein Haus und notiert: sechs Ziegelsteine, eine Tür, vier Wasserhähne. Er legt keine echten Ziegel auf den Tisch, nur die Liste. Der Lieferdienst liest sie und liefert passende Teile ans Grundstück. Das fertige Lager auf dem Grundstück entsteht aus der Liste.

Node.js ist die Laufzeitumgebung, die JavaScript außerhalb des Browsers ausführt. Die Liste ist package.json, das zentrale Dokument jedes Node-Projekts. npm, der Paketmanager von Node.js, liest diese Datei und lädt aus dem zentralen Paketarchiv, der Registry, die nötigen Bausteine herunter. Sie landen im Ordner node_modules, der alle installierten Pakete samt deren eigenen Abhängigkeiten enthält.

Eine Abhängigkeit (Dependency) ist ein fremdes Programmpaket, das der eigene Code zum Laufen braucht, etwa Express für HTTP-Anfragen. In package.json steht unter dependencies der Eintrag "express": "^4.18.0". Das Caret vor der Zahl erlaubt jede 4er-Version ab 4.18.0; die drei Ziffern 1.2.3 bedeuten major.minor.patch – brechende Änderung, neue Funktion, Fehlerbehebung.

Das Bild hat eine Grenze: Eine Einkaufsliste nennt Zutaten meist exakt, "^4.18.0" ist ein erlaubter Bereich. Ohne die Sperrdatei package-lock.json kann npm auf einem Rechner 1.2.3 wählen, auf einem anderen 1.9.0. Die Sperrdatei friert die tatsächlich gewählten Versionen ein.

Deshalb gilt: package.json und package-lock.json gehören in die Versionsverwaltung (Git), node_modules nicht. Die Liste reicht, um überall dieselben Bausteine neu zu bestellen.

📌 Abhängigkeit · Versionsbereich · Sperrdatei

📚 Webentwicklung von Grund auf · Tag 4 von 30
#NodeJS #javascript #webdev
Lena Peters
2 Tage vor
Der Code hängt an einer await-Zeile – oder scheint es zu tun. Dabei wartet dort nur eine einzige Funktion, nicht das ganze Programm.

Symptom kennen viele aus ihren ersten Webprojekten: Eine Variable enthält nach einem Serveraufruf nichts Brauchbares. Stattdessen steckt darin ein Objekt namens Promise, obwohl man doch die Daten erwartet hatte.

Hinter dem Symptom steht ein Grundbegriff: das Promise, ein Behälter für ein Ergebnis, das erst später eintrifft. JavaScript wartet nicht gern: Läuft eine Anfrage an einen Server, gibt der Aufruf sofort das Promise zurück – noch ohne Inhalt. Die Event-Loop, also die zentrale Verwaltung, die Aufgaben nacheinander abarbeitet, läuft währenddessen munter weiter. Würde der Code wirklich anhalten und warten, stünde die gesamte Anwendung still. Das Promise ist der Trick, beides zu vermeiden: Aufrufer bekommen sofort etwas in der Hand, die Daten folgen später.

Konkret: In einer mit async markierten Funktion, die immer ein Promise zurückgibt, schreibt man const antwort = await fetch("/artikel/42"); fetch ist der Browser-Befehl für eine HTTP-Anfrage. Erst nach Ankunft der Serverantwort liefert await das Antwortobjekt mit den Daten. Wichtig: await pausiert allein die umgebende Funktion; andere Aufgaben, etwa weitere eingehende HTTP-Anfragen, laufen weiter. async und await sind also keine Paralleltechnik, sondern eine lesbare Schreibweise für Promise-Ketten.

So prüft man es: Nach dem Aufruf den Inhalt der Variablen ausgeben lassen. Steht dort ein Promise statt der Daten, fehlt await. Und die await-Zeile in try und catch packen, damit eine Ablehnung des Promise, also ein fehlgeschlagenes Ergebnis, nicht als unbehandelter Fehler durchgeht.

await heißt nicht „Programm anhalten“, sondern „nur diese Funktion pausieren, bis das Promise ein Ergebnis liefert“.

📌 Promise · await · Event-Loop

📚 Webentwicklung von Grund auf · Tag 4 von 30
#javascript #typescript #webdev
Lena Peters
2 Tage vor
Die meisten denken, ein Server brauche für jede Anfrage einen eigenen Thread. Dabei kommt Node.js mit einem einzigen Hauptthread aus und steht trotzdem nie still.

Verantwortlich dafür ist die Event-Loop, eine laufende Schleife im Hauptthread. Sie prüft, ob abgeschlossene Hintergrundvorgänge Ergebnisse geliefert haben, und ruft dann die zugehörigen Funktionen auf.

🌐 Eine gestartete Lese- oder Netzwerkoperation gibt den Hauptthread sofort frei. Das nennt man asynchron: Das Programm wartet nicht, sondern arbeitet weiter und kommt später zurück, wenn das Ergebnis bereitliegt. Ein Callback ist eine Funktion, die als Argument mitgegeben und beim Eintritt des Ereignisses aufgerufen wird. Bei await verbirgt der Compiler genau dieses Muster hinter einer scheinbar linearen Schreibweise.

🧩 „Asynchron“ heißt nicht „parallel“. Es gibt nur einen Hauptthread, der nacheinander arbeitet. Liest ein Server eine Datei mit fs.readFile, kann er währenddessen weitere HTTP-Anfragen annehmen; mit fs.readFileSync stehen alle anderen Anfragen still. Der Fortschritt entsteht durch Weiterarbeiten während des Wartens, nicht durch gleichzeitige Ausführung.

🔒 Eine blockierte Event-Loop ist kein Leistungsproblem, sondern ein Stillstand. Auch JSON.parse und JSON.stringify sind synchron; sehr große Dokumente halten die Schleife für die Dauer der Verarbeitung an. Dann steht jede Anfrage still, weil schlicht nichts mehr ausgeführt wird. Node.js empfiehlt daher, CPU-intensive Arbeit in Worker Threads auszulagern, eigene Threads mit eigenem Event-Loop und Nachrichtenaustausch.

Asynchron heißt nicht „schneller rechnen“, sondern „weiterarbeiten, während gewartet wird“.

📌 Event-Loop · Asynchron · Hauptthread

📚 Webentwicklung von Grund auf · Tag 4 von 30
#NodeJS #javascript #webdev
Lena Peters
2 Tage vor
Viele Einsteiger halten JavaScript für eine Browsersprache. Dabei läuft dieselbe Sprache auch auf Servern und Build-Werkzeugen.

Die Annahme klingt plausibel: JavaScript entstand für Webseiten, und dort sieht man es auch. Wer Buttons, Formulare und Animationen kennt, verbindet die Sprache fest mit Browser und Frontend.

Tatsächlich ist der Browser nur eine Laufzeitumgebung – also das Programm, das die Sprache überhaupt ausführen kann. Es enthält die Sprach-Engine und Bibliotheken, über die der Code sein Betriebssystem erreicht. Die Sprache selbst definiert die ECMAScript-Norm, und jede Umgebung legt fest, was sie darf. Node.js ist eine solche Umgebung und führt JavaScript außerhalb des Browsers aus, etwa auf einem Server. Sie ergänzt die Sprache um Module für Dateizugriffe und um eines, das einen HTTP-Server startet, der Anfragen entgegennimmt und antwortet.

Der Irrtum entsteht, weil Einsteiger JavaScript fast ausschließlich im Frontend erleben. Dort laufen die Sprache und der Browser scheinbar immer gemeinsam auf.

Ein kleines Skript zeigt den Unterschied: Unter Node.js liest es eine Datei ein und zählt Wörter. Genau dieses JavaScript hat vorher vielleicht einen Button im Browser verarbeitet. Wird daraus ein Server, beantwortet er etwa die Anfrage GET /artikel/42 mit einem Datensatz im JSON-Format.

Woran man es erkennt: Läuft Code ohne geöffnetes Browserfenster, ist er nicht im Frontend, sondern im Backend unterwegs. Frontend und Backend sind keine Ordner, sondern Lauforte derselben Sprache.

JavaScript heißt nicht „die Browsersprache“, sondern eine Sprache mit wechselnden Lauforten. Wer Werkzeuge wie npm nutzt, fährt bereits Node.js, ohne es zu bemerken.

📌 Laufzeitumgebung · Node.js · Frontend und Backend als Lauforte

📚 Webentwicklung von Grund auf · Tag 4 von 30
#javascript #NodeJS #webdev
Lena Peters
2 Tage vor
Die Antwort der API kommt zurück, aber das Frontend zeigt nichts an. Der Grund ist oft ein einziges falsches Komma im JSON.

Das Symptom: Der Browser meldet einen Fehler beim Auslesen der Daten. Die Anfrage selbst war erfolgreich; nur der Text der Antwort lässt sich nicht in ein Objekt umwandeln.

Dahinter steckt JSON, das JavaScript Object Notation, ein reines Textformat und der verbreitete Standard für Daten von Web-APIs. JSON kennt Objekte mit Schlüssel-Wert-Paaren, Listen, Zeichenketten, Zahlen sowie true, false und null. Der Browser fragt etwa per GET /artikel/42 einen Datensatz an, und der Server antwortet im Body, dem Teil der Antwort mit den eigentlichen Nutzdaten. Ein Header wie Content-Type: application/json kündigt dabei das Format an.

Ein typischer Fehler: einfache statt doppelter Anführungszeichen oder ein Komma nach dem letzten Paar. Beides macht das JSON ungültig, und der Empfänger verweigert das Lesen. Korrekt verschachtelt kombiniert eine Antwort beides: ein Objekt mit Metadaten wie der Gesamtzahl 2 sowie eine Liste in eckigen Klammern mit zwei Artikeln, den Nummern 42 und 43 und den Titeln „Neu“ und „Alt“ – Objekte und Listen lassen sich beliebig ineinander verschachteln.

So prüft man es: Die Antwort in einen JSON-Validator kopieren, der ungültige Stellen markiert. In JavaScript prüft JSON.parse den Text und meldet die Stelle, an der etwas fehlt; JSON.stringify wandelt ein Objekt wieder in Text um.

Wer null sieht, sollte zudem wissen: Das heißt, ein Wert fehlt bewusst – anders als die Zahl 0 oder eine leere Zeichenkette, bei denen ein Wert vorhanden ist.

JSON heißt nicht „irgendein Textformat“, sondern Objekte, Listen und Werte in exakter Schreibweise – doppelte Anführungszeichen, kein Schlusskomma.

📌 JSON-Objekt · Listen · null statt 0

📚 Webentwicklung von Grund auf · Tag 3 von 30
#webdev #api #javascript #frontend
Lena Peters
3 Tage vor
JavaScript kann Bilder von fremden Servern laden, aber nicht deren pixelgenaue Daten auslesen. Dieser Unterschied ist die Same-Origin-Policy – und sie erklärt, warum fetch-Aufrufe scheitern können, obwohl die Anfrage beim Server ankam.

Der Browser vergleicht bei jeder Antwort, ob sie von derselben Origin (der Kombination aus Schema, Host und Port) stammt wie die Seite, deren JavaScript sie lesen will. Das begegnet Einsteigern sofort, sobald Frontend und Backend getrennt laufen.

Zuerst lädt der Browser die Seite, etwa eine gewöhnliche Dokumentseite unter https. JavaScript auf dieser Seite ruft dann Daten ab, zum Beispiel von einer API unter einem anderen Host. Die Anfrage geht ganz normal raus; der Server antwortet, ohne zu prüfen, wer sie liest.

Dann zählt der Browser Schema, Host und Port, nicht den Pfad: Zwei Adressen wie /seite1 und /api/daten auf demselben Host mit demselben Port teilen sich eine Origin. Aber ein API-Host und ein www-Host derselben Domain sind verschiedene Hosts, und derselbe Host mit abweichendem Port wie 8443 ist eine andere Origin. Ein fehlender Port bedeutet den Standardport, also 443 bei https.

Danach hält der Browser die Antwort zurück, wenn die Origins verschieden sind. Der Browser schickt die Anfrage, gibt die Antwort aber nicht an JavaScript weiter, solange der Server sie nicht per CORS (einem Header-Mechanismus zur Freigabe) erlaubt. Bilder und Stylesheets fremder Origins erscheinen trotzdem, weil kein Skript ihren Inhalt liest.

Zuletzt gilt die Grenze nur im Browser. curl (ein Kommandozeilenwerkzeug für HTTP-Anfragen) sendet und liest ohne Sandbox alles; die Same-Origin-Policy schützt den Server nicht, nur die Seite im Browser.

Gleiche Origin heißt also nicht gleicher Host, und fremde Origin heißt nicht blockierte Anfrage – sondern unlesbare Antwort.

📌 Origin · Same-Origin-Policy · CORS

📚 Webentwicklung von Grund auf · Tag 3 von 30
#WebSecurity #webdev #javascript
Lena Peters
3 Tage vor
Die meisten denken, eine Webadresse sei ein einziger unteilbarer String. Dabei vergleicht der Browser nur drei Bestandteile, um Herkünfte zu unterscheiden.

Die Verwechslung ist naheliegend: URL und Origin sehen fast gleich aus, und die Origin ist der vordere Teil der URL. Wer beides gleichsetzt, wundert sich später, warum eine Anfrage blockiert wird.

Die URL (Uniform Resource Locator, eine komplette Webadresse) besteht aus Schema, Host, optionalem Port, Pfad, optionaler Query nach dem Fragezeichen und optionalem Fragment nach der Raute. Sie benennt eine konkrete Ressource wie eine Seite oder ein Bild. Schema https, Pfad /orders und Query id=7 zeigen vier dieser Bestandteile in einer Adresse.

Die Origin besteht nur aus Schema, Host und Port; der Rest zählt nicht mit. Der Browser vergleicht zwei Adressen, indem er genau diese drei Teile gegenüberstellt; eine Abweichung ergibt eine andere Origin. Zwei Adressen mit gleichem Host sind darum verschieden, sobald der Port abweicht (Standardport gegenüber 8443) oder das Schema (http gegenüber https).

Pfad, Query und Fragment dürfen beliebig abweichen, ohne die Origin zu ändern. Ein fehlender Port bedeutet zudem den Standardport des Schemas – bei https der 443, bei http der 80; eine Adresse mit und ohne diese 443 hat dieselbe Origin.

Faustregel: Beim Aufrufen einer Ressource die volle URL angeben, beim Prüfen von Herkunft und Zugriff nur Schema, Host und Port vergleichen. Auch Unterdomänen wie api und www desselben Namens sind verschiedene Hosts und damit verschiedene Origins; die Same-Origin-Policy, eine Browser-Regel, gibt JavaScript nur Antworten derselben Origin frei, fremde Origins brauchen eine CORS-Freigabe des Servers.

Die Origin heißt nicht Adresse, sondern Herkunft: Schema, Host und Port – und sonst nichts.

📌 Origin · Same-Origin-Policy · URL-Bestandteile

📚 Webentwicklung von Grund auf · Tag 3 von 30
#webdev #WebSecurity #HTTP
Lena Peters
3 Tage vor
Die meisten Anfänger denken, der Server müsse das Cookie abfragen oder der Nutzer müsse es eintippen. Dabei übernimmt der Browser den Versand des Cookies, eines kleinen Name-Wert-Paars, vollständig automatisch.

HTTP, das Protokoll hinter Webseiten, ist zustandslos – jede Anfrage steht für sich. Ohne zurückgesendete Daten wüsste der Server nicht, wer fragt. Cookies füllen genau diese Lücke.

🌐 Ein Cookie ist ein Name-Wert-Paar, das der Server setzt. In der Antwort steht etwa: Set-Cookie: sessionid=abc123; Path=/; HttpOnly. Vor dem Semikolon stehen Name und Wert, die Attribute dahinter steuern Speicherung und Versand. Path=/ bedeutet: zu jedem Pfad dieses Hosts mitsenden.

🧩 Der Browser schickt das Cookie automatisch mit, ohne eigenes Programm. Passt die angefragte Adresse zum Cookie, fügt der Browser den Header Cookie: sessionid=abc123 in die Anfrage ein. Die Webanwendung muss nichts dafür tun. Derselbe Datensatz heißt in der Antwort Set-Cookie, in der Anfrage Cookie – zwei Header, ein Inhalt. Nachvollziehen lässt sich das in den Entwicklerwerkzeugen: im Netzwerk-Tab bei einer Antwort den Set-Cookie-Header suchen und bei der nächsten Anfrage an denselben Host den Cookie-Header mit demselben Wert vergleichen.

🔒 HttpOnly schützt den Cookie vor JavaScript im Browser. JavaScript kann ihn dann nicht auslesen, und ein XSS-Angriff (böses Skript auf der Seite) stiehlt ihn nicht direkt. Ohne Expires oder Max-Age gilt das Cookie nur bis zum Schließen des Browsers. Das nennt man Sitzungscookie; der Browser kann die Sitzung aber wiederherstellen.

Ein Cookie heißt nicht Abfrage durch den Server, sondern automatischer Rückversand durch den Browser. Der Server erkennt Nutzer wieder, indem er den Wert etwa in seiner Session-Tabelle nachschlägt.

📌 Name-Wert-Paar · Set-Cookie · automatischer Rückversand

📚 Webentwicklung von Grund auf · Tag 2 von 30
#webdev #HTTP #backend
Lena Peters
4 Tage vor
Die meisten Einsteiger denken, eine Webseite sei ein einziger Ort. Dabei läuft sie an zwei Orten: im Browser und auf dem Server.

Wer nicht weiß, welcher Baustein wo läuft, baut Prüfregeln an den falschen Ort. Und der falsche Ort ist der, den jeder Besucher verändern kann.

🌐 Frontend und Backend sind keine Ordner, sondern Lauforte. Das Frontend ist der Teil, der im Browser läuft: HTML beschreibt die Struktur, CSS das Aussehen, JavaScript das Verhalten auf der Seite. Das Backend läuft auf dem Server, speichert Daten und stellt Schnittstellen bereit. Dieselbe Sprache JavaScript kann an beiden Orten laufen: im Browser oder mit Node.js auf dem Server.

🧩 Der Browser spricht mit dem Backend über HTTP, das Anfrage-Antwort-Protokoll des Webs. Eine Schnittstelle (API) liefert etwa mit GET /artikel/42 einen Datensatz, oft als JSON, einem einfachen Textformat für Daten. Der Server kann dieselbe Adresse unterschiedlich beantworten: dem Browser eine HTML-Seite, einem Programm JSON-Daten. Er weiß dabei nie, was gerade angezeigt wird; jede Anfrage muss alles enthalten, was er zum Prüfen braucht.

🔒 Sensible Daten und alle Prüfregeln gehören immer ins Backend. Der JavaScript-Code im Browser ist sichtbar und veränderbar. Ein Kontaktformular prüft dort per JavaScript, ob das E-Mail-Feld ausgefüllt ist, und markiert den Fehler sofort. Das Backend prüft dieselbe Eingabe trotzdem erneut, weil die Frontend-Prüfung mit den Entwicklerwerkzeugen abgeschaltet sein kann.

Frontend heißt nicht „der sichere Teil der Anwendung“, sondern der Teil auf dem Gerät des Besuchers. Deshalb gilt: Ob eine Eingabe gilt, prüft der Server, nicht der Browser.

📌 Frontend · Backend · Serverprüfung

📚 Webentwicklung von Grund auf · Tag 2 von 30
#frontend #backend #webdev
Lena Peters
4 Tage vor
Viele Einsteiger schreiben ihr Webseiten-Aussehen direkt in den HTML-Code. Dabei haben die drei Websprachen längst klare Aufgaben verteilt: Struktur, Aussehen, Verhalten.

Man begegnet ihnen bei jeder Seite im Browser. Wer die Trennung nicht kennt, ändert später jede Datei einzeln und sammelt Fehler, statt sie zu vermeiden.

Das Frontend, also der Teil einer Anwendung, der im Browser läuft, nutzt drei Sprachen mit getrennten Aufgaben. HTML beschreibt Struktur und Inhalt, CSS das Aussehen, JavaScript das Verhalten. HTML ist eine Auszeichnungssprache: Elemente wie Überschriften und Links teilen dem Browser mit, welche Bedeutung ein Textteil hat. CSS besteht aus Regeln mit Selektor, der bestimmt, welche Elemente gemeint sind, und Deklarationen wie color: red, die das Aussehen festlegen. JavaScript ist eine Programmiersprache und reagiert etwa auf Klicks, ohne die Seite neu zu laden.

Ein Beispiel: ein Button, in HTML mit dem button-Element ausgezeichnet, sagt dem Browser „hier steht etwas Klickbares“. Eine CSS-Regel färbt seine Schrift rot, etwa mit color: red. Ein Klick darauf löst JavaScript aus, das per Programmierung ein Dankeschön einblendet. Drei Dateien, drei Aufgaben, ein zusammenwirkendes Ergebnis.

Verwechselt wird die Trennung oft mit der zwischen Frontend und Backend. Das Backend läuft auf dem Server, speichert Daten und stellt Schnittstellen bereit. Hier geht es aber um die Rollen innerhalb einer einzigen HTML-Seite im Browser. Der typische Irrtum: Aussehen direkt in HTML-Attribute schreiben. Dann muss man bei einer Designänderung jede Seite einzeln anfassen; mit getrennter CSS-Datei genügt eine Änderung für alle.

HTML ist also nicht der Ort für Farben oder Logik, sondern nur für Bedeutung und Struktur. Wer die Aufgaben trennt, wartet eine Änderung an genau einer Stelle.

📌 HTML · CSS · JavaScript

📚 Webentwicklung von Grund auf · Tag 1 von 30
#webdev #frontend #javascript
Herr Herco
3 Monate vor
💡 Warum WebAssembly (Wasm) die Zukunft der Softwareentwicklung verändert

JavaScript hat das Web aufgebaut, aber WebAssembly (Wasm) definiert gerade seine Grenzen neu.

🚀Wasm ist kein Ersatz für JavaScript, sondern der Turbo an seiner Seite. Es handelt sich um ein binäres Codeformat, das Code aus performanten Sprachen wie Rust, C++ oder Go mit nahezu nativer Geschwindigkeit direkt im Browser ausführt.

Warum ist das ein Game-Changer?
Brachiale Performance: Perfekt für rechenintensive Aufgaben wie Bildbearbeitung (z. B. Figma, Photoshop Web), 3D-Gaming und KI-Modelle direkt auf dem Client.Maximale Sicherheit: Der Code läuft isoliert in einer sicheren Sandbox im Browser.

Nicht mehr nur im Web: Dank WASI (WebAssembly System Interface) erobert Wasm gerade den Server- und Cloud-Bereich als blitzschnelle, leichtgewichtige Alternative zu Docker-Containern.

Die Ära, in der komplexe Software zwingend installiert werden musste, ist vorbei. Das Web ist die universelle Plattform – angetrieben von WebAssembly.

#WebAssembly #WASM #WebDevelopment #SoftwareEngineering #TechTrends #cloudnative
Herr Herco
3 Monate vor
WebAssembly ist die Antwort auf die unangenehmste Frage im Agenten-Bau: Wem gibst du eigentlich exec?

Jeder, der ein Plugin-System für einen LLM-Agenten baut, landet irgendwann an derselben Stelle. Der Kern funktioniert, der Tool-Loop läuft, und dann sollen Erweiterungen dazukommen – von Nutzern, von Kollegen, aus dem Netz. Und plötzlich steht die Frage im Raum, über die in Demos nie gesprochen wird:

Was darf dieser fremde Code auf meinem Rechner eigentlich?

Die ehrliche Antwort lautet bei den meisten Setups: alles. Ein Plugin ist ein Skript, das Skript läuft im selben Prozess wie der Agent, der Agent hat deine API-Keys in der Umgebung, dein Dateisystem unter sich und eine offene Netzverbindung. Zwischen "nützliche Erweiterung" und "Exfiltration deiner Secrets" liegt genau nichts – außer Vertrauen.

Das ist der Punkt, an dem WebAssembly aufhört, ein Browser-Thema zu sein.

WASM IST KEIN SCHNELLERES JAVASCRIPT. ES IST EIN SICHERHEITSMODELL.

Die meiste Aufmerksamkeit für WebAssembly dreht sich um Performance. Interessanter ist aber die Eigenschaft, die WASM von Anfang an mitbringt und die andere Plugin-Formate mühsam nachrüsten müssen: Ein WASM-Modul kann per Konstruktion nichts.

Kein Dateisystem. Kein Netz. Keine Uhr, keine Umgebungsvariablen, keine Syscalls. Ein WASM-Modul sitzt in einem linearen Speicherbereich und hat exakt die Fähigkeiten, die der Host ihm als Funktionen hineinreicht – nicht eine mehr. Der Default ist nicht "großzügig". Der Default ist leer.

Damit dreht sich die Beweislast um. Bei einem nativen Plugin muss man einschränken, was es kann. Bei einem WASM-Plugin muss man erlauben, was es können soll. Ein kleiner Unterschied in der Formulierung – ein sehr großer in der Praxis.

WIE WIR DAS IN SEPP MINI NUTZEN

Ich baue sepp mini: einen leichtgewichtigen, erweiterbaren Agent-Harness in Rust. Eine statische Binary, kein Node, kein Ballast. Ein Agenten-Loop mit Streaming, parallelem Tool-Dispatch und Compaction – nutzbar als TUI, als One-shot-Kommando oder als JSONL-RPC zum Einbetten in andere Programme.

Erweiterbarkeit ist dort in vier Tiers geschichtet, gestuft nach Macht und Isolation:

Tier 1 – Resources: Skills, Prompt-Templates, Themes. Reine Daten, kein Code.

Tier 2 – Hooks: In-process Rhai-Skripte, die den Agent-Loop steuern. Sprach-Sandbox.

Tier 3 – WASM: Plugins aus jeder Sprache, memory-sandboxed via wasmi.

Tier 4 – MCP: Out-of-process-Server als Tool-Quelle, OS-sandboxed.

Je mehr eine Erweiterung darf, desto härter isoliert sie der Kern.

Tier 3 ist die Stelle, an der WebAssembly genau das liefert, was sonst teuer ist: echter Fremdcode ohne echtes Risiko. Ein Plugin deklariert im Manifest seine Capabilities – FsRead, FsWrite, Net, Env, Exec. Der Kern parst das zu einer Policy, der Mensch bestätigt sie, und dann registriert der Host nur die Funktionen, die die Policy erlaubt.

Der entscheidende Satz daran: Ein Plugin ohne Net-Capability bekommt keine Netz-Host-Funktion. Es ist damit nicht "gebeten, nicht ins Netz zu gehen" – es ist nachweislich offline. Es gibt keinen Syscall, den es aufrufen könnte. Der Default ist deny, und deny ist hier keine Konfiguration, sondern eine Abwesenheit.

Dazu kommt: Ein .wasm-Modul ist sprachagnostisch. Rust, Go, TinyGo, C, Zig, AssemblyScript – wer ein Plugin schreiben will, muss nicht meine Sprache lernen, sondern nur mein Interface treffen. Für ein Open-Source-Projekt ist das der Unterschied zwischen einem Ökosystem und einem Monolog.

WAS WASM NICHT LÖST – UND WOFÜR WIR DAS BETRIEBSSYSTEM BRAUCHEN

Ehrlichkeit gehört dazu, sonst wird es Marketing: WASM ist keine Universallösung.

Ein WASM-Modul kann keinen git-Prozess starten, keinen Language-Server sprechen, keine bestehende CLI wrappen. Sobald eine Erweiterung wirklich Prozesse ausführen muss, hilft keine Memory-Sandbox – dann muss die Grenze dorthin, wo sie hart ist: ins Betriebssystem. Genau dafür existiert Tier 4. MCP-Server laufen out-of-process, OS-sandboxed über Landlock unter Linux und Seatbelt (sandbox_init) unter macOS, beides fail-closed, plus Environment-Scrubbing – damit ein Subprozess keine API-Keys erbt, die ihm niemand geben wollte.

Die Architektur-Aussage ist also nicht "WASM für alles". Sie lautet: Die Isolationsmethode folgt der geforderten Macht. Daten brauchen keine Sandbox. Logik braucht eine Memory-Sandbox. Prozesse brauchen das OS. WebAssembly besetzt in dieser Staffelung die mittlere – und aus meiner Sicht wertvollste – Stufe: mächtig genug für echte Logik, isoliert genug, um Fremdcode ohne Bauchschmerzen laufen zu lassen.

WARUM DAS JETZT ZÄHLT

Agenten schreiben Code, führen ihn aus, rufen Tools auf. Das Ökosystem drumherum wächst schneller, als die Sicherheitsmodelle nachgezogen werden. Wir werden in den nächsten Jahren sehr viele Agent-Erweiterungen aus sehr unterschiedlichen Quellen installieren – und die Frage "was darf das eigentlich?" wird von einer Detailfrage zur zentralen Frage.

WebAssembly beantwortet sie mit dem einzigen Default, der skaliert: nichts, bis jemand etwas anderes sagt.

sepp mini ist Open Source, Rust, eine statische Binary, Linux und macOS inklusive Apple Silicon.

https://sepp.kionova.de

Wer selbst an Plugin- oder Sandbox-Architekturen für Agenten arbeitet: Ich bin ernsthaft an Gegenargumenten interessiert. Wo seht ihr die Grenzen des Capability-Ansatzes?

#WebAssembly #WASM #Rust #aiagents #opensource #SoftwareArchitecture
Lena Peters
9 Monate vor
TypeScript oder JavaScript für neue Projekte? #typescript #javascript #umfrage

TypeScript immer

Kommt drauf an

JavaScript reicht

Bun mit TS

18 Menschen haben abgestimmt

Nichts gefunden!

Entschuldigung, aber für Ihre Suchanfrage {{search_query}} konnten wir in unserer Datenbank nichts finden. Bitte versuchen Sie es erneut, indem Sie andere Suchbegriffe eingeben.