Page.js — это легковесная библиотека для клиентской маршрутизации на
стороне браузера, позволяющая строить одностраничные приложения с
поддержкой истории навигации. Одним из ключевых аспектов маршрутизации
является обработка Query String — параметров,
передаваемых в URL после знака ?. Правильная и безопасная
работа с ними важна для корректного поведения приложения и
предотвращения потенциальных уязвимостей.
Page.js предоставляет возможность определять маршруты с параметрами и
работать с объектом ctx в функции-обработчике. Объект
ctx содержит информацию о текущем маршруте, включая Query
String.
Пример базового маршрута с Query String:
page('/search', function(ctx) {
console.log(ctx.querystring); // raw query string: "q=javascript&page=2"
});
Здесь ctx.querystring возвращает строку после
? без декодирования. Для работы с параметрами удобно
использовать стандартный объект URLSearchParams.
page('/search', function(ctx) {
const params = new URLSearchParams(ctx.querystring);
const query = params.get('q'); // "javascript"
const pageNum = params.get('page'); // "2"
});
Использование URLSearchParams позволяет
безопасно извлекать параметры без необходимости ручного
парсинга строки, что снижает риск ошибок и уязвимостей.
Для генерации ссылок с Query String важно избегать ручной
конкатенации строк, чтобы не допустить инъекций или
некорректного кодирования. Page.js не занимается автоматическим
кодированием, поэтому необходимо использовать
encodeURIComponent:
const query = 'JavaScript & Page.js';
const pageNum = 2;
const url = `/search?q=${encodeURIComponent(query)}&page=${encodeURIComponent(pageNum)}`;
page(url);
Такой подход предотвращает проблемы с символами &,
= и другими специальными символами в URL.
Page.js позволяет создавать динамические сегменты URL, например
/user/:id. При необходимости сочетать динамические сегменты
с Query String, значения параметров хранятся в ctx.params,
а Query String — в ctx.querystring.
page('/user/:id', function(ctx) {
const userId = ctx.params.id; // значение из сегмента URL
const params = new URLSearchParams(ctx.querystring);
const tab = params.get('tab'); // значение параметра tab
});
Такое разделение помогает структурировать данные маршрута, снижая вероятность смешения динамических сегментов и Query String.
Query String может быть источником ненадежных данных, особенно если URL формируется пользователем. Для безопасной работы рекомендуется:
if (!params.has('q')) {
page.redirect('/search?q=default');
}
const pageNum = parseInt(params.get('page'), 10);
if (isNaN(pageNum) || pageNum < 1) {
pageNum = 1;
}
const safeQuery = query.replace(/</g, "<").replace(/>/g, ">");
Page.js позволяет изменять маршрут и Query String без полной
перезагрузки через page.show:
const params = new URLSearchParams();
params.set('q', 'Page.js');
params.set('page', 3);
page.show(`/search?${params.toString()}`);
Использование URLSearchParams.toString() гарантирует
корректное кодирование параметров и совместимость с
различными браузерами.
Если приложение использует прямые переходы по URL (например, при F5 или внешней ссылке), нужно уметь извлекать параметры на этапе инициализации:
page('*', function(ctx) {
const params = new URLSearchParams(ctx.querystring);
// глобальная обработка параметров
});
Использование маршрута '*' позволяет захватывать все URL
и работать с Query String до передачи управления специфическим
маршрутам.
encodeURIComponent для генерации
ссылок.URLSearchParams(ctx.querystring).ctx.params) и Query
String (ctx.querystring).encodeURIComponent или
URLSearchParams.toString().page.show.Эти практики обеспечивают корректное и безопасное взаимодействие с Query String в одностраничных приложениях на Page.js, минимизируя ошибки и уязвимости.