Контекст запроса

В библиотеке Page.js контекст запроса является ключевым элементом для управления маршрутизацией и обработки переходов между страницами. Контекст передаётся каждому обработчику маршрута и предоставляет всю необходимую информацию о текущем состоянии маршрута, параметрах URL и объекте события. Понимание контекста критично для построения динамических приложений на стороне клиента.

Основные свойства контекста

Объект контекста, передаваемый в колбэк маршрута, включает несколько важных свойств:

  • path — полный путь текущего маршрута, включая все сегменты и параметры запроса. Например, при URL /users/42?tab=info свойство path будет равно /users/42?tab=info.
  • params — объект, содержащий динамические параметры маршрута. Если маршрут объявлен как /users/:id, а URL /users/42, то ctx.params.id вернёт 42. Параметры автоматически декодируются из URL.
  • querystring — строка запроса после знака ?, например tab=info&sort=asc. Она не распарсена и остаётся в виде строки. Для работы с query-параметрами рекомендуется использовать утилиты вроде URLSearchParams.
  • hash — фрагмент URL после #. Например, для URL /users#section2 значение будет #section2.
  • state — объект состояния истории (History API), который может использоваться для хранения данных между переходами без изменения URL.

Методы контекста

Объект контекста предоставляет несколько методов, упрощающих навигацию и управление маршрутизацией:

  • ctx.redirect(path) — позволяет программно перенаправить пользователя на другой маршрут. При вызове происходит смена URL и вызов соответствующего обработчика маршрута.
  • ctx.save() — сохраняет текущее состояние маршрута в истории браузера. Полезно для SPA, где нужно сохранять пользовательские данные между переходами.
  • ctx.pushState() и ctx.replaceState() — низкоуровневые методы для работы с History API. pushState создаёт новую запись истории, а replaceState заменяет текущую.

Динамические параметры

Динамические сегменты маршрута объявляются с помощью двоеточия :. Page.js автоматически разбирает URL и формирует объект params. Примеры использования:

page('/users/:id', ctx => {
    console.log(ctx.params.id); // выводит значение параметра id
});

Для маршрутов с несколькими параметрами:

page('/users/:userId/posts/:postId', ctx => {
    console.log(ctx.params.userId, ctx.params.postId);
});

При этом Page.js корректно обрабатывает URL-кодирование, позволяя использовать любые символы в параметрах.

Работа с query-параметрами и hash

Page.js не парсит query-параметры по умолчанию, поэтому для работы с ними рекомендуется использовать встроенный объект URLSearchParams:

page('/search', ctx => {
    const params = new URLSearchParams(ctx.querystring);
    console.log(params.get('q')); // значение параметра q
});

Hash-фрагменты доступны через свойство ctx.hash и могут быть использованы для прокрутки страницы к определённым элементам:

page('/users', ctx => {
    if (ctx.hash === '#top') {
        window.scrollTo(0, 0);
    }
});

Взаимодействие с историей браузера

Page.js интегрируется с History API, что позволяет управлять историей и состоянием SPA без перезагрузки страницы. Контекст предоставляет доступ к ctx.state и методам pushState/replaceState:

page('/dashboard', ctx => {
    ctx.state.lastVisited = new Date();
    ctx.pushState(ctx.state, '', '/dashboard');
});

Это позволяет сохранять пользовательские данные, такие как фильтры или позиция прокрутки, и восстанавливать их при возвращении на страницу.

Middleware и контекст

Page.js поддерживает цепочку middleware, каждый элемент которой получает один и тот же объект контекста. Это позволяет централизованно обрабатывать авторизацию, загрузку данных или модификацию параметров:

page('*', ctx => {
    ctx.user = getCurrentUser(); // добавление данных пользователя в контекст
    ctx.next();
});

page('/profile', ctx => {
    console.log(ctx.user.name);
});

Синхронизация с внешними данными

Объект контекста часто используется для передачи данных между обработчиками маршрутов и компонентами интерфейса. Например, загрузка данных с API перед рендером страницы:

page('/posts/:id', async ctx => {
    ctx.post = await fetch(`/api/posts/${ctx.params.id}`).then(res => res.json());
    renderPost(ctx.post);
});

Использование контекста в таком виде позволяет создавать структурированные, модульные SPA, где маршруты и данные связаны напрямую.

Контекст запроса в Page.js является ядром маршрутизации, объединяя информацию о URL, параметрах, состоянии истории и вспомогательные методы для управления навигацией. Понимание и правильное использование всех его свойств обеспечивает гибкую и мощную архитектуру клиентских приложений.