Menu

express.static : servir des fichiers statiques avec Express

app.use(express.static(path.join(__dirname, 'public'))) sert chaque fichier du dossier public à l'URL correspondante : public/style.css répond à /style.css. Ajoutez un chemin de montage pour les servir sous un préfixe.

Cette page contient des éditeurs exécutables. Modifiez, exécutez et voyez la sortie instantanément.

express.static est le middleware intégré qui sert les fichiers d'un dossier. app.use(express.static(path.join(__dirname, 'public'))) rend chaque fichier de public accessible au même chemin dans l'URL : public/style.css répond à /style.css, et public/index.html répond à /. Express définit le Content-Type à partir de l'extension du fichier, et quand aucun fichier ne correspond, il passe la requête à vos routes au lieu de répondre 404.

La réponse à GET /style.css est le texte du fichier, avec Content-Type: text/css; charset=utf-8 dans l'onglet Headers. Envoyez GET / pour obtenir index.html, puis GET /api/time : ce fichier n'existe pas, donc c'est la route qui répond.

Pourquoi le chemin du dossier a besoin de __dirname

express.static('public') résout 'public' par rapport au dossier depuis lequel vous avez lancé Node, pas au dossier où se trouve server.js. Cela marche quand vous lancez node server.js dans le projet, et casse quand un gestionnaire de processus ou un script démarre l'application depuis un autre endroit :

// 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') désigne le dossier à côté du fichier qui contient la ligne, quel que soit l'endroit d'où Node a été lancé. Dans un module ES, utilisez path.join(import.meta.dirname, 'public') (Node 20.11 et suivants). La page sur le module path détaille __dirname et path.join.

Servir des fichiers sous un préfixe

Passez d'abord un chemin de montage pour servir le dossier sous un préfixe d'URL. Le préfixe ne fait pas partie du chemin du fichier sur le disque :

GET /assets/app.js renvoie console.log("hi"); en text/javascript, et GET /assets/img/dot.svg va chercher dans le sous-dossier. Envoyez GET /app.js sans le préfixe : c'est un 404, car les fichiers n'existent que sous /assets. Utilisez un préfixe pour éviter que les URL des fichiers entrent en conflit avec vos routes d'API.

En-têtes de cache avec maxAge

Par défaut, Express envoie Cache-Control: public, max-age=0, donc les navigateurs vérifient auprès du serveur à chaque utilisation (et obtiennent un 304 Not Modified rapide quand le fichier n'a pas changé, grâce à l'en-tête ETag). Pour les fichiers dont le nom change à chaque build, comme app.3f9a1c.js, dites aux navigateurs de les garder :

Ouvrez l'onglet Headers : Cache-Control vaut maintenant public, max-age=604800, sept jours en secondes. index: false désactive l'envoi de index.html pour les URL de dossiers. D'autres options utiles : extensions: ['html'], qui permet à /about de trouver about.html, et dotfiles, qui vaut 'ignore' par défaut pour que des fichiers comme .env ne soient jamais servis.

Applications single page : revenir à index.html

Une application React ou Vue construite pour le routing côté client a besoin que tout chemin inconnu renvoie index.html, pour qu'un rechargement sur /settings ne donne pas un 404. Placez ce fallback après express.static et vos routes d'API :

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'));
});

Erreurs fréquentes

Mettre le nom du dossier dans l'URL. Avec app.use(express.static('public')), l'URL est /style.css, pas /public/style.css. Si vous voulez /public dans l'URL, montez-le : app.use('/public', express.static(...)).

Lier les fichiers avec des chemins relatifs dans le HTML. <link href="style.css"> sur la page /blog/post demande /blog/style.css. Commencez le chemin par une barre oblique : /style.css.

Mettre des secrets dans le dossier statique. Tout ce qu'il contient est public. Gardez-en à l'écart les fichiers de configuration, les clés et le code source.

Questions fréquentes

Peut-on utiliser express.static plusieurs fois ?

Oui. Enregistrez-en un par dossier ; Express les parcourt dans l'ordre où vous les avez ajoutés et sert le premier fichier trouvé. Donnez à chacun son propre chemin de montage quand les dossiers peuvent contenir des fichiers du même nom.

Express doit-il servir les fichiers statiques en production ?

Pour les petites applications, ça va. Pour un trafic important, placez devant un CDN ou un reverse proxy comme Nginx, qui sert les fichiers plus vite et les met en cache plus près des utilisateurs, et gardez Express pour l'API.

Comment envoyer un fichier précis depuis une route ?

Utilisez res.sendFile(path.join(__dirname, 'files', 'report.pdf')). Le chemin doit être absolu (ou vous passez une option root). Utilisez plutôt res.download() quand le navigateur doit enregistrer le fichier au lieu de l'afficher.

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

Commencer