Menu

express.static: Statische Dateien in Express ausliefern

app.use(express.static(path.join(__dirname, 'public'))) liefert jede Datei im Ordner public unter der passenden URL aus: public/style.css beantwortet /style.css. Mit einem Einhängepfad liegen sie unter einem Präfix.

Diese Seite enthält ausführbare Editoren. Bearbeiten, ausführen und Ausgabe sofort sehen.

express.static ist die eingebaute Middleware, die Dateien aus einem Ordner ausliefert. app.use(express.static(path.join(__dirname, 'public'))) macht jede Datei in public unter demselben Pfad in der URL erreichbar: public/style.css beantwortet /style.css, und public/index.html beantwortet /. Express setzt den Content-Type anhand der Dateiendung, und wenn keine Datei passt, gibt es die Anfrage an deine Routen weiter, statt mit 404 zu antworten.

Die Antwort auf GET /style.css ist der Text der Datei, mit Content-Type: text/css; charset=utf-8 im Headers-Tab. Sende GET /, um index.html zu bekommen, dann GET /api/time: Eine solche Datei gibt es nicht, also antwortet die Route.

Warum der Ordnerpfad __dirname braucht

express.static('public') löst 'public' relativ zu dem Ordner auf, aus dem du Node gestartet hast, nicht zu dem Ordner, in dem server.js liegt. Das funktioniert, wenn du node server.js im Projekt ausführst, und bricht, wenn ein Prozessmanager oder ein Skript die App von woanders startet:

// project/server.js uses express.static('public')
// cd project && node server.js      -> serves project/public
// node project/server.js            -> looks for ./public, every file is 404

path.join(__dirname, 'public') ist der Ordner neben der Datei, die diese Zeile enthält, egal, wo Node gestartet wurde. In einem ES-Modul nimmst du path.join(import.meta.dirname, 'public') (ab Node 20.11). Die Seite zum path-Modul behandelt __dirname und path.join im Detail.

Dateien unter einem Präfix ausliefern

Übergib zuerst einen Einhängepfad, um den Ordner unter einem URL-Präfix auszuliefern. Das Präfix gehört nicht zum Pfad der Datei auf der Festplatte:

GET /assets/app.js liefert console.log("hi"); als text/javascript, und GET /assets/img/dot.svg greift in den Unterordner. Sende GET /app.js ohne Präfix: Das ist ein 404, weil die Dateien nur unter /assets existieren. Mit einem Präfix kollidieren Datei-URLs nicht mit deinen API-Routen.

Cache-Header mit maxAge

Standardmäßig sendet Express Cache-Control: public, max-age=0, Browser fragen also bei jeder Nutzung beim Server nach (und bekommen dank des ETag-Headers ein schnelles 304 Not Modified, wenn sich die Datei nicht geändert hat). Für Dateien, deren Namen sich bei jedem Build ändern, etwa app.3f9a1c.js, sag Browsern, dass sie sie behalten sollen:

Öffne den Headers-Tab: Cache-Control ist jetzt public, max-age=604800, sieben Tage in Sekunden. index: false schaltet das Ausliefern von index.html für Ordner-URLs ab. Weitere nützliche Optionen sind extensions: ['html'], womit /about die Datei about.html findet, und dotfiles, das standardmäßig 'ignore' ist, damit Dateien wie .env nie ausgeliefert werden.

Single Page Apps: Fallback auf index.html

Eine React- oder Vue-App mit Client-seitigem Routing braucht für jeden unbekannten Pfad index.html, damit ein Neuladen auf /settings keinen 404 ergibt. Setz den Fallback hinter express.static und deine API-Routen:

app.use(express.static(path.join(__dirname, 'dist')));
app.use('/api', apiRouter);

// Express 5 wildcard syntax
app.get('/*splat', (req, res) => {
    res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});

Häufige Fehler

Den Ordnernamen in die URL schreiben. Mit app.use(express.static('public')) ist die URL /style.css, nicht /public/style.css. Wenn du /public in der URL willst, häng es ein: app.use('/public', express.static(...)).

Dateien in HTML mit relativen Pfaden verlinken. <link href="style.css"> auf der Seite /blog/post fragt nach /blog/style.css. Beginn den Pfad mit einem Schrägstrich: /style.css.

Geheimnisse in den static-Ordner legen. Alles darin ist öffentlich. Halte Konfigurationsdateien, Schlüssel und Quellcode da raus.

Häufig gestellte Fragen

Kann ich express.static mehrmals verwenden?

Ja. Registrier eines pro Ordner; Express sucht in der Reihenfolge, in der du sie hinzugefügt hast, und liefert die erste gefundene Datei aus. Gib jedem einen eigenen Einhängepfad, wenn die Ordner Dateien mit gleichem Namen enthalten könnten.

Sollte Express in Produktion statische Dateien ausliefern?

Für kleine Apps ist das in Ordnung. Bei viel Traffic stell ein CDN oder einen Reverse Proxy wie Nginx davor, der Dateien schneller ausliefert und näher an den Nutzern cacht, und nutz Express für die API.

Wie sende ich aus einer Route eine bestimmte Datei?

Mit res.sendFile(path.join(__dirname, 'files', 'report.pdf')). Der Pfad muss absolut sein (oder du übergibst eine root-Option). Nimm stattdessen res.download(), wenn der Browser die Datei speichern statt anzeigen soll.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

Los geht's