Параметры и query-строки

Одним из мощных инструментов фреймворка Marko для работы с динамическими данными и их представлением является механизм обработки параметров и query-строк. Этот функционал позволяет строить гибкие и масштабируемые приложения, которые могут взаимодействовать с внешними источниками данных, передавать параметры в шаблоны и обрабатывать запросы с динамическими значениями.

Использование параметров в шаблонах

Параметры в Marko — это значения, передаваемые в компоненты шаблонов. Они позволяют задавать динамические данные, которые компонент может использовать в своем рендеринге. Параметры передаются в компонент через его атрибуты в момент рендеринга. Например:

<my-component title="Hello World" />

В этом примере компонент my-component получает параметр title со значением "Hello World". Для доступа к этому значению внутри компонента используется синтаксис:

<div>${input.title}</div>

Здесь input.title обращается к значению параметра title, переданному в компонент. Важно отметить, что параметры, передаваемые в компоненты, могут быть как статическими (как в примере выше), так и динамическими, вычисляемыми в процессе выполнения.

Работа с query-строками

Query-строки — это часть URL, которая содержит параметры, передаваемые серверу в виде пар «ключ-значение». Они часто используются для фильтрации, сортировки или поиска данных на сервере. В Marko можно работать с query-строками для получения данных, переданных через URL.

Для работы с query-строками в Marko используется объект req.query в контексте серверного рендеринга. Он содержит все параметры, переданные через URL. Например, при запросе:

https://example.com/products?category=electronics&sort=price

объект req.query будет выглядеть следующим образом:

{
  category: 'electronics',
  sort: 'price'
}

Пример использования query-строк в Marko

Допустим, нужно отобразить список товаров на основе категории и параметра сортировки, переданных через query-строку. Для этого в компоненте можно использовать данные из req.query, передавая их в шаблон:

const marko = require('marko');

module.exports = async function (req, res) {
  const category = req.query.category || 'all';
  const sort = req.query.sort || 'name';

  const products = await getProducts(category, sort); // функция получения данных

  res.marko(template, {
    category,
    sort,
    products
  });
};

В шаблоне можно использовать переданные параметры:

<div>
  <h1>Products in ${input.category} category</h1>
  <p>Sorted by: ${input.sort}</p>
  <ul>
    <for|product of input.products|>
      <li>${product.name}</li>
    </for>
  </ul>
</div>

Здесь, в зависимости от значений query-строки, будет отображаться список товаров с соответствующей категорией и сортировкой.

Обработка отсутствующих параметров

Параметры query-строк не всегда могут быть переданы в запросе. В таких случаях важно грамотно обрабатывать отсутствие данных. Обычно это делается с помощью значений по умолчанию. В примере выше, если в query-строке не переданы параметры category или sort, то они получают значения по умолчанию ('all' и 'name' соответственно).

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

Валидация и безопасность параметров

Когда параметры передаются через query-строки, важно всегда проверять и валидировать их, чтобы предотвратить потенциальные уязвимости, такие как SQL-инъекции или XSS-атаки. В Marko это можно сделать, проверяя типы и диапазоны значений параметров перед их использованием. Например:

const category = req.query.category;
if (!category || !['electronics', 'fashion', 'books'].includes(category)) {
  // Возвращаем ошибку или выполняем действие по умолчанию
  res.status(400).send('Invalid category');
}

Для предотвращения XSS-атак также важно экранировать данные перед выводом их на страницу:

<div>${input.category}</div> <!-- Экранируется автоматически -->

Marko автоматически экранирует данные, передаваемые через параметры, если они выводятся с помощью синтаксиса ${}. Однако важно следить за тем, чтобы любые данные, полученные от пользователя, проходили необходимую проверку.

Преобразование данных параметров

Иногда параметры query-строк могут требовать преобразования перед использованием. Например, если параметр сортировки передан в виде строки ("price"), а сортировать нужно по числовым значениям, то его нужно привести к числовому типу:

const sortBy = parseInt(req.query.sort) || 'name';

Иногда параметры могут быть массивами, если в URL передано несколько значений для одного ключа. Например:

https://example.com/products?category=electronics&category=fashion

В таком случае req.query.category будет массивом, содержащим значения:

['electronics', 'fashion']

Для обработки таких случаев можно использовать методы работы с массивами, такие как .map(), .filter() и другие.

Примеры использования параметров в URL

Работа с параметрами в URL и query-строках в Marko позволяет создавать динамичные и адаптивные интерфейсы. Вот несколько примеров, когда параметры и query-строки могут быть полезны:

  1. Фильтрация товаров: передача параметров для выбора категории или диапазона цен.
  2. Пагинация: использование параметров для отображения различных страниц данных, например, page=2 и limit=10.
  3. Поиск: параметр запроса для передачи строки поиска, например, q=mobile+phones.

Эти параметры могут передаваться и обрабатываться как на клиенте, так и на сервере. Важно учитывать, что для серверного рендеринга Marko предоставляет гибкие механизмы для работы с запросами и параметрами, что позволяет строить масштабируемые и эффективные решения.

Заключение

Использование параметров и query-строк в Marko открывает широкие возможности для создания динамических веб-приложений. Важность правильной обработки данных, их валидации и преобразования не должна быть недооценена, так как это напрямую влияет на безопасность и производительность приложения. Правильное использование этих инструментов позволяет строить гибкие интерфейсы и взаимодействовать с внешними источниками данных.