Практика №8. SSR-сервер с динамической генерацией страниц

Общее описание

В рамках этого задания вам необходимо создать сервер на NodeJS, который реализует Server-Side Rendering (SSR) — динамическую генерацию HTML-страниц на основе данных, хранящихся в памяти. Сервер должен отдавать полностью готовые HTML-страницы при запросах к корневому пути / и к динамическому пути /task/:id, без использования клиентского JavaScript для рендеринга. Все данные формируются на сервере, ответы содержат структурированный HTML с встроенными стилями и ссылками. Никаких внешних библиотек — только встроенные модули NodeJS: http, path.

Задание обязано быть опубликовано в новом приватном репозитории организации GitHub с названием Группа_Фамилия_task-8.

Ресурсы

(пусто)

Техническое задание

Создайте HTTP-сервер на NodeJS, который:

1. Обрабатывает два маршрута:

  • GET / — отдаёт главную страницу со списком всех задач
  • GET /task/:id — отдаёт страницу одной задачи, где :id — целое число (например, /task/2)

2. Использует фиксированный массив задач:

const tasks = [
  { id: 1, title: 'Выучить JavaScript', completed: false },
  { id: 2, title: 'Создать Todo-приложение', completed: true },
  { id: 3, title: 'Настроить сервер', completed: false }
];

3. Для / должен отдавать HTML-страницу с:

  • Заголовком <h1>Мои задачи</h1>
  • Списком задач в <ul> — каждый элемент <li> содержит название задачи
  • Для задач с completed: true — добавлять класс completed в <li>
  • Внутренним стилем в <head>:
    .completed { text-decoration: line-through; color: #999; }
    
  • Пустым <script></script> в конце <body> (для имитации гидратации)
  • Корректным <!DOCTYPE html> и мета-тегом кодировки
  • Content-Type: text/html

4. Для /task/:id должен отдавать HTML-страницу с:

  • Заголовком <h1>Задача #<id></h1>
  • Данными задачи:
    • <p><strong>Название:</strong> <span>...</span></p>
    • <p><strong>Статус:</strong> <span>Выполнена</span></p> или <p><strong>Статус:</strong> <span>Не выполнена</span></p>
  • Кнопкой «Назад» с ссылкой на /
  • Корректным <!DOCTYPE html> и мета-тегом кодировки
  • Content-Type: text/html

5. Обработка ошибок:

  • Если :id не существует в массиве — отдаётся страница 404 с содержимым:
    <h1>404</h1>
    <p>Задача с таким ID не найдена.</p>
    
  • Если :id — не число или пустой — отдаётся 404
  • Для всех остальных путей (например, /about, /api/users) — отдаётся 404
  • Не используйте fs.readFileSync() — только асинхронные методы (fs.readFile() не требуется, так как данные в памяти)

6. Технические требования:

  • Используйте только встроенные модули: http, path
  • Никаких внешних библиотек (Express, etc.)
  • Никакого клиентского рендеринга — все HTML генерируется на сервере
  • Никаких fetch() или innerHTML — страницы должны быть полностью готовы при приходе запроса
  • Устанавливайте правильный Content-Type для всех ответов
  • Обработка путей — через req.url и строковую манипуляцию (split(), startsWith(), parseInt())
  • Сервер должен слушать порт 3000

7. Примеры ответов:

Запрос: GET /
Ответ:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Задачи</title>
  <style>
    .completed { text-decoration: line-through; color: #999; }
  </style>
</head>
<body>
  <h1>Мои задачи</h1>
  <ul>
    <li>Выучить JavaScript</li>
    <li class="completed">Создать Todo-приложение</li>
    <li>Настроить сервер</li>
  </ul>
  <script></script>
</body>
</html>

Запрос: GET /task/2
Ответ:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Задача #2</title>
</head>
<body>
  <h1>Задача #2</h1>
  <p><strong>Название:</strong> <span>Создать Todo-приложение</span></p>
  <p><strong>Статус:</strong> <span>Выполнена</span></p>
  <p><a href="/">← Назад</a></p>
</body>
</html>

Запрос: GET /task/999
Ответ:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>404</title>
</head>
<body>
  <h1>404</h1>
  <p>Задача с таким ID не найдена.</p>
</body>
</html>

Время на выполнение

На выполнение выделяется 3 практических пары.
Градация баллов после дедлайна:

  • 1 пара: 50%
  • 2 пара: 25%
  • 3 пара: 0%

Баллы

Статус выполнения Количество баллов
Не сдано -3
Сдано 7