В библиотеке Page.js middleware представляет собой функцию, которая обрабатывает событие навигации перед окончательной загрузкой контента или рендером страницы. Каждая функция middleware получает объект context и функцию next, через которую управление передаётся следующей функции в цепочке. Структура типичного middleware выглядит так:
function middleware(ctx, next) {
// логика обработки
next(); // передача управления следующему middleware
}
Middleware можно использовать для:
Page.js позволяет регистрировать middleware как глобально, так и на уровне конкретного маршрута. Глобальные middleware выполняются для всех маршрутов, а локальные — только для указанного.
// Глобальные middleware
page(middleware1);
page(middleware2);
// Локальные middleware для маршрута /dashboard
page('/dashboard', authMiddleware, dataLoader, dashboardView);
Важно: порядок регистрации имеет критическое значение. Middleware выполняются строго в том порядке, в котором они зарегистрированы.
Middleware может содержать асинхронные операции. Важно корректно использовать next, чтобы не блокировать цепочку:
function fetchDataMiddleware(ctx, next) {
fetch(`/api/data${ctx.path}`)
.then(response => response.json())
.then(data => {
ctx.data = data;
next();
})
.catch(err => {
console.error(err);
page.redirect('/error');
});
}
Если next не вызывается, цепочка middleware прерывается, и последующие функции не выполняются. Это позволяет реализовать условия остановки, например, при отсутствии прав доступа.
function authMiddleware(ctx, next) {
if (ctx.user.isAuthenticated) {
next();
} else {
page.redirect('/login');
}
}
function stateMiddleware(ctx, next) {
ctx.state = {
timestamp: Date.now(),
pageTitle: 'Demo'
};
next();
}
function errorHandler(ctx, next) {
try {
next();
} catch (err) {
console.error('Ошибка в middleware:', err);
page.redirect('/error');
}
}
Middleware имеет доступ к параметрам маршрута через объект ctx.params. Это позволяет динамически подгружать данные или изменять поведение приложения:
page('/user/:id', userMiddleware, userView);
function userMiddleware(ctx, next) {
const userId = ctx.params.id;
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(user => {
ctx.user = user;
next();
});
}
Цепочка middleware позволяет разделять ответственность и писать модульный код:
Это создаёт чистую и предсказуемую структуру, где каждая функция выполняет одну задачу и передаёт управление дальше.
page(
'/dashboard',
authMiddleware,
fetchDashboardData,
injectUIState,
renderDashboard
);
const dashboardMiddleware = [authMiddleware, fetchDashboardData, injectUIState];
page('/dashboard', ...dashboardMiddleware, renderDashboard);
page('/settings', ...dashboardMiddleware, renderSettings);
function conditionalMiddleware(ctx, next) {
if (ctx.user.isAdmin) {
page('/admin');
} else {
next();
}
}
Для контроля выполнения middleware можно использовать логирование контекста:
function logger(ctx, next) {
console.log('Путь:', ctx.path);
console.log('Параметры:', ctx.params);
next();
}
Также полезно визуализировать порядок вызова middleware через последовательные консольные сообщения или специальные флаги в контексте.
Эффективное использование цепочек middleware в Page.js позволяет строить модульные, расширяемые и легко поддерживаемые SPA-приложения, где каждая логическая операция изолирована и легко тестируема.