En aquest tema, aprendrem com servir fitxers estàtics com HTML, CSS, JavaScript, imatges, etc., utilitzant Node.js. Els fitxers estàtics són aquells que no canvien en resposta a les peticions dels usuaris i són essencials per a la majoria de les aplicacions web.
Objectius
- Entendre què són els fitxers estàtics.
- Aprendre a servir fitxers estàtics amb Node.js.
- Utilitzar el mòdul
fs
per llegir fitxers. - Configurar correctament els tipus MIME per als fitxers servits.
Què són els Fitxers Estàtics?
Els fitxers estàtics són aquells que no canvien en resposta a les peticions dels usuaris. Aquests inclouen:
- HTML
- CSS
- JavaScript
- Imatges (JPEG, PNG, GIF, etc.)
- Fonts
Servir Fitxers Estàtics amb Node.js
Pas 1: Configurar un Servidor HTTP Bàsic
Primer, configurem un servidor HTTP bàsic. Si no estàs familiaritzat amb això, revisa el tema anterior sobre Crear un Servidor HTTP Simple.
const http = require('http'); const fs = require('fs'); const path = require('path'); const server = http.createServer((req, res) => { // Aquí anirà el codi per servir fitxers estàtics }); const PORT = 3000; server.listen(PORT, () => { console.log(`Servidor escoltant a http://localhost:${PORT}`); });
Pas 2: Llegir i Servir Fitxers
Utilitzarem el mòdul fs
per llegir els fitxers del sistema de fitxers i servir-los com a resposta a les peticions HTTP.
const http = require('http'); const fs = require('fs'); const path = require('path'); const server = http.createServer((req, res) => { // Determinar el camí del fitxer sol·licitat let filePath = path.join(__dirname, 'public', req.url === '/' ? 'index.html' : req.url); // Extensió del fitxer let extname = path.extname(filePath); // Tipus MIME per defecte let contentType = 'text/html'; // Mapear l'extensió del fitxer a un tipus MIME switch (extname) { case '.js': contentType = 'text/javascript'; break; case '.css': contentType = 'text/css'; break; case '.json': contentType = 'application/json'; break; case '.png': contentType = 'image/png'; break; case '.jpg': contentType = 'image/jpg'; break; case '.wav': contentType = 'audio/wav'; break; } // Llegir el fitxer fs.readFile(filePath, (err, content) => { if (err) { if (err.code == 'ENOENT') { // Pàgina no trobada fs.readFile(path.join(__dirname, 'public', '404.html'), (err, content) => { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(content, 'utf8'); }); } else { // Alguna errada del servidor res.writeHead(500); res.end(`Error del servidor: ${err.code}`); } } else { // Èxit res.writeHead(200, { 'Content-Type': contentType }); res.end(content, 'utf8'); } }); }); const PORT = 3000; server.listen(PORT, () => { console.log(`Servidor escoltant a http://localhost:${PORT}`); });
Explicació del Codi
-
Determinació del Camí del Fitxer:
let filePath = path.join(__dirname, 'public', req.url === '/' ? 'index.html' : req.url);
Això determina el camí del fitxer sol·licitat. Si la URL és
/
, serviràindex.html
. -
Determinació del Tipus MIME:
let extname = path.extname(filePath); let contentType = 'text/html'; switch (extname) { case '.js': contentType = 'text/javascript'; break; case '.css': contentType = 'text/css'; break; case '.json': contentType = 'application/json'; break; case '.png': contentType = 'image/png'; break; case '.jpg': contentType = 'image/jpg'; break; case '.wav': contentType = 'audio/wav'; break; }
Això mapeja l'extensió del fitxer a un tipus MIME adequat.
-
Llegir i Servir el Fitxer:
fs.readFile(filePath, (err, content) => { if (err) { if (err.code == 'ENOENT') { fs.readFile(path.join(__dirname, 'public', '404.html'), (err, content) => { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(content, 'utf8'); }); } else { res.writeHead(500); res.end(`Error del servidor: ${err.code}`); } } else { res.writeHead(200, { 'Content-Type': contentType }); res.end(content, 'utf8'); } });
Això llegeix el fitxer del sistema de fitxers i l'envia com a resposta. Si el fitxer no es troba, serveix una pàgina
404.html
.
Exercici Pràctic
Exercici 1: Servir Fitxers Estàtics
- Crea una carpeta anomenada
public
al mateix nivell que el teu fitxer de servidor. - Dins de la carpeta
public
, crea un fitxerindex.html
amb el següent contingut:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="styles.css"> </head> <body> <h1>Hola, Node.js!</h1> <script src="app.js"></script> </body> </html>
- Crea un fitxer
styles.css
dins de la carpetapublic
amb el següent contingut:body { font-family: Arial, sans-serif; background-color: #f0f0f0; text-align: center; padding: 50px; }
- Crea un fitxer
app.js
dins de la carpetapublic
amb el següent contingut:console.log('Hola des de app.js!');
Solució
Després de crear els fitxers, executa el servidor i visita http://localhost:3000
al teu navegador. Hauries de veure la pàgina HTML servida amb els estils aplicats i el missatge de la consola del navegador.
Conclusió
En aquest tema, hem après com servir fitxers estàtics utilitzant Node.js. Hem configurat un servidor HTTP bàsic, hem llegit fitxers del sistema de fitxers i els hem servit com a resposta a les peticions HTTP. També hem après a configurar correctament els tipus MIME per als fitxers servits. Aquest coneixement és fonamental per a qualsevol desenvolupador web que treballi amb Node.js.
Curs de Node.js
Mòdul 1: Introducció a Node.js
Mòdul 2: Conceptes Bàsics
Mòdul 3: Sistema de Fitxers i I/O
Mòdul 4: HTTP i Servidors Web
Mòdul 5: NPM i Gestió de Paquets
Mòdul 6: Framework Express.js
- Introducció a Express.js
- Configuració d'una Aplicació Express
- Middleware
- Routing en Express
- Gestió d'Errors
Mòdul 7: Bases de Dades i ORMs
- Introducció a les Bases de Dades
- Utilitzar MongoDB amb Mongoose
- Utilitzar Bases de Dades SQL amb Sequelize
- Operacions CRUD
Mòdul 8: Autenticació i Autorització
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb Mocha i Chai
- Proves d'Integració
- Depuració d'Aplicacions Node.js
Mòdul 10: Temes Avançats
Mòdul 11: Desplegament i DevOps
- Variables d'Entorn
- Utilitzar PM2 per a la Gestió de Processos
- Desplegar a Heroku
- Integració i Desplegament Continu