In this section, we will learn how to serve static files using Node.js. Static files include HTML, CSS, JavaScript, images, and other resources that do not change dynamically. Serving static files is a common requirement for web applications, and Node.js provides several ways to achieve this.

Key Concepts

  1. Static Files: Files that do not change dynamically and are served as-is to the client.
  2. HTTP Server: A server that listens for HTTP requests and serves responses.
  3. File System Module: A Node.js module that allows interaction with the file system.
  4. Path Module: A Node.js module that provides utilities for working with file and directory paths.

Steps to Serve Static Files

  1. Set Up a Basic HTTP Server: Create a simple HTTP server using the http module.
  2. Read Static Files: Use the fs module to read static files from the file system.
  3. Serve Static Files: Send the static files as responses to HTTP requests.

Example: Serving Static Files

Step 1: Set Up a Basic HTTP Server

First, let's create a basic HTTP server that listens for incoming requests.

const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
    // Handle requests here
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server is listening on port ${PORT}`);
});

Step 2: Read Static Files

Next, we will read static files from the file system. For this example, let's assume we have an index.html file in a public directory.

<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Static File Example</title>
</head>
<body>
    <h1>Hello, World!</h1>
</body>
</html>

Step 3: Serve Static Files

We will modify our server to serve the index.html file when the root URL (/) is requested.

const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
    if (req.url === '/') {
        const filePath = path.join(__dirname, 'public', 'index.html');
        fs.readFile(filePath, (err, content) => {
            if (err) {
                res.writeHead(500, { 'Content-Type': 'text/plain' });
                res.end('Internal Server Error');
            } else {
                res.writeHead(200, { 'Content-Type': 'text/html' });
                res.end(content);
            }
        });
    } else {
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('Not Found');
    }
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server is listening on port ${PORT}`);
});

Handling Different File Types

To serve different types of static files (e.g., CSS, JavaScript, images), we need to determine the content type based on the file extension.

const mimeTypes = {
    '.html': 'text/html',
    '.css': 'text/css',
    '.js': 'application/javascript',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
    '.gif': 'image/gif'
};

const server = http.createServer((req, res) => {
    let filePath = path.join(__dirname, 'public', req.url === '/' ? 'index.html' : req.url);
    const extname = String(path.extname(filePath)).toLowerCase();
    const contentType = mimeTypes[extname] || 'application/octet-stream';

    fs.readFile(filePath, (err, content) => {
        if (err) {
            if (err.code === 'ENOENT') {
                res.writeHead(404, { 'Content-Type': 'text/plain' });
                res.end('Not Found');
            } else {
                res.writeHead(500, { 'Content-Type': 'text/plain' });
                res.end('Internal Server Error');
            }
        } else {
            res.writeHead(200, { 'Content-Type': contentType });
            res.end(content);
        }
    });
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server is listening on port ${PORT}`);
});

Practical Exercise

Exercise: Serve Static Files

  1. Create a directory named public in your project root.
  2. Add an index.html file, a style.css file, and a script.js file to the public directory.
  3. Modify the server code to serve these files based on the request URL.

Solution

// public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Static File Example</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>Hello, World!</h1>
    <script src="script.js"></script>
</body>
</html>

// public/style.css
body {
    background-color: #f0f0f0;
    font-family: Arial, sans-serif;
}

// public/script.js
console.log('Hello from script.js');

// server.js
const http = require('http');
const fs = require('fs');
const path = require('path');

const mimeTypes = {
    '.html': 'text/html',
    '.css': 'text/css',
    '.js': 'application/javascript',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
    '.gif': 'image/gif'
};

const server = http.createServer((req, res) => {
    let filePath = path.join(__dirname, 'public', req.url === '/' ? 'index.html' : req.url);
    const extname = String(path.extname(filePath)).toLowerCase();
    const contentType = mimeTypes[extname] || 'application/octet-stream';

    fs.readFile(filePath, (err, content) => {
        if (err) {
            if (err.code === 'ENOENT') {
                res.writeHead(404, { 'Content-Type': 'text/plain' });
                res.end('Not Found');
            } else {
                res.writeHead(500, { 'Content-Type': 'text/plain' });
                res.end('Internal Server Error');
            }
        } else {
            res.writeHead(200, { 'Content-Type': contentType });
            res.end(content);
        }
    });
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server is listening on port ${PORT}`);
});

Summary

In this section, we learned how to serve static files using Node.js. We covered the following key points:

  • Setting up a basic HTTP server.
  • Reading static files from the file system.
  • Serving static files based on the request URL.
  • Handling different file types using MIME types.

By understanding these concepts, you can now serve static files in your Node.js applications, providing essential resources like HTML, CSS, and JavaScript to your users.

Node.js Course

Module 1: Introduction to Node.js

Module 2: Core Concepts

Module 3: File System and I/O

Module 4: HTTP and Web Servers

Module 5: NPM and Package Management

Module 6: Express.js Framework

Module 7: Databases and ORMs

Module 8: Authentication and Authorization

Module 9: Testing and Debugging

Module 10: Advanced Topics

Module 11: Deployment and DevOps

Module 12: Real-World Projects

© Copyright 2024. All rights reserved