Промежуточные обработчики (middleware) в Page.js представляют собой функции, которые выполняются до основного обработчика маршрута и позволяют управлять потоком навигации, проверять условия доступа, модифицировать параметры запроса и подготавливать данные для последующего использования. Они обеспечивают гибкость и масштабируемость маршрутизации, особенно в приложениях с большим числом маршрутов.
Промежуточные функции подключаются с помощью метода
page() аналогично маршрутам, но без обязательного указания
конечного обработчика:
page('/dashboard', checkAuth, loadUserData, showDashboard);
Здесь checkAuth и loadUserData —
промежуточные обработчики, а showDashboard — конечный
обработчик маршрута. Каждый промежуточный обработчик получает
три аргумента:
function middleware(ctx, next) {
// ctx — объект контекста маршрута
// next — функция для передачи управления следующему обработчику
}
ctx.params), query-параметры
(ctx.querystring), а также ссылку на текущий URL
(ctx.path) и другие данные.next() не вызывается, цепочка обработки
останавливается.Все промежуточные обработчики вызываются в порядке их объявления. Пример:
page('/profile/:id', checkAuth, fetchProfile, renderProfile);
function checkAuth(ctx, next) {
if (!ctx.user) {
page.redirect('/login');
} else {
next();
}
}
function fetchProfile(ctx, next) {
api.getUserProfile(ctx.params.id).then(profile => {
ctx.profile = profile;
next();
});
}
function renderProfile(ctx) {
document.body.innerHTML = `<h1>${ctx.profile.name}</h1>`;
}
checkAuth проверяет авторизацию и при необходимости
перенаправляет.fetchProfile получает данные пользователя и сохраняет
их в ctx.renderProfile использует данные из ctx для
отображения страницы.Глобальные middleware применяются ко всем маршрутам:
page('*', logNavigation);
function logNavigation(ctx, next) {
console.log('Переход на:', ctx.path);
next();
}
'*' означает, что обработчик сработает для
любого маршрута.Локальные middleware подключаются к конкретному маршруту и выполняются только для него:
page('/admin', checkAdmin, renderAdmin);
Page.js полностью поддерживает асинхронные операции через промисы или async/await:
page('/posts/:id', async function loadPost(ctx, next) {
try {
ctx.post = await api.getPost(ctx.params.id);
next();
} catch (err) {
page.redirect('/error');
}
});
next() не вызывается после завершения асинхронной
операции, маршрут не продолжится.Middleware обеспечивает удобный доступ к параметрам маршрута и строке запроса:
page('/search/:term', parseQuery, showResults);
function parseQuery(ctx, next) {
const params = new URLSearchParams(ctx.querystring);
ctx.filters = params.get('filter') || 'all';
next();
}
ctx.params.term содержит динамический сегмент URL.ctx.querystring предоставляет доступ к GET-параметрам,
которые можно обработать в middleware.Промежуточные обработчики могут останавливать цепочку или перенаправлять пользователя:
function requireLogin(ctx, next) {
if (!ctx.user) {
page.redirect('/login');
} else {
next();
}
}
Page.js поддерживает цепочки middleware:
page('/dashboard', [checkAuth, fetchSettings, fetchNotifications], renderDashboard);
ctx для передачи данных:
middleware могут обогащать контекст информацией, которая понадобится
последующим обработчикам.next() вызывается только если дальнейшее выполнение
маршрута допустимо.Промежуточные обработчики в Page.js превращают маршрутизацию в мощный инструмент управления приложением, позволяя контролировать поток данных, права доступа и предварительную подготовку контента без дублирования кода.