Menu
CoddyTech

Tệp tĩnh

Thuộc phần Kiến thức cơ bản về Express trong hành trình Node.js của Coddy. Bài học 11 trên 23.

Tệp CSS hoặc hình ảnh không bao giờ thay đổi, còn tạo một route cho mỗi tệp thì chỉ thêm việc không cần thiết.

app.use(express.static('assets'));

express.static('assets') cung cấp các tệp trong thư mục assets theo tên của chúng: assets/logo.png phản hồi yêu cầu GET /logo.png. Tên thư mục không nằm trong URL. Express chọn kiểu nội dung dựa trên phần mở rộng: text/css cho .css, image/png cho .png. Đường dẫn không có tệp tương ứng sẽ tiếp tục được chuyển đến các route của bạn.

app.use thêm một hàm chạy mỗi khi có yêu cầu; chương tiếp theo sẽ nói về các hàm đó. Giờ đây, dự án của bạn có thư mục public chứa một tệp CSS.

challenge icon

Thử thách

Dễ

Recipe Box có thêm bảng kiểu. Tệp đã sẵn sàng trong thư mục public; máy chủ của bạn chỉ cần cung cấp tệp đó.

  1. Trong server.js, ngay sau const app = express();, hãy cung cấp mọi tệp trong thư mục public bằng express.static. Sau đó, public/style.css sẽ được cung cấp tại /style.css.
  2. Để trang chủ tải tệp này: đặt <link rel="stylesheet" href="/style.css"> ở đầu HTML mà tuyến / gửi đi.

Thử nhé: Nhấn Chạy và gửi /. Trang hiện sử dụng bảng kiểu. Gửi /style.css: trạng thái 200, nội dung CSS và Content-Type là text/css trong thẻ Headers. Gửi /missing.css: không có tệp như vậy, nên yêu cầu được chuyển tiếp đến các tuyến của bạn. Không tuyến nào khớp, và Express phản hồi bằng mã 404.

Tự làm thử

import {escapeHtml} from './html.js';
import express from 'express';
import { recipes } from './data.js';

const app = express();



app.get('/', (req, res) => {
    const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
    res.send(`<h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});

// type('text') gửi văn bản thuần túy, nên mỗi tiêu đề hiển thị trên một dòng riêng.
app.get('/recipes', (req, res) => {
    const { tag } = req.query;
    const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
    res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});

app.get('/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).send('No such recipe');
        return;
    }
    res.send(recipe.title);
});

app.get('/api/recipes', (req, res) => {
    res.json(recipes);
});

app.get('/api/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).json({ error: 'No such recipe' });
        return;
    }
    res.json(recipe);
});

app.get('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});

Tất cả bài học trong Kiến thức cơ bản về Express

Tự luyện tập: Playground Express