Веб‑сервис «Гадалка» (или любой другой API, принимающий параметры в URL) часто использует строку запроса (query string) для передачи данных. Если в эти параметры попадают специальные символы, они могут нарушить синтаксис URL, привести к ошибкам парсинга или, что ещё хуже, стать причиной уязвимостей (SQL‑инъекции, XSS и т.п.). Поэтому правильное экранирование — обязательный шаг при формировании запросов.
Почему экранирование так важно?
- Синтаксическая корректность. Спецсимволы (пробел, «&», «=», «?», «#», «%» и др.) имеют особое значение в URL.
- Безопасность. Неэкранированные данные могут быть интерпретированы сервером как часть кода.
- Совместимость. Разные браузеры и серверные фреймворки по‑разному обрабатывают некорректные запросы.
Какие символы считаются «специальными»?
Согласно RFC 3986, в URL необходимо экранировать:
- Пробел () →
%20(или+вapplication/x-www-form-urlencoded). - Символы резервации:
! * ' ( ) ; : @ & = + $ , / ? # [ ]. - Не ASCII‑символы (кириллица, китайские иероглифы и т.д.) → их UTF‑8‑байты, закодированные в
%XX.
Основные способы экранирования
3.1 URL‑энкодинг (percent‑encoding)
Самый универсальный метод – преобразовать каждый «опасный» символ в его шестнадцатеричное представление, предварённое знаком «%». В большинстве языков есть готовые функции:
| Язык | Функция | Пример |
|---|---|---|
| PHP | urlencode / rawurlencode | urlencode('привет мир') → %D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82+%D0%BC%D0%B8%D1%80 |
| JavaScript | encodeURIComponent | encodeURIComponent('привет мир') → %D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80 |
| Python | urllib.parse.quote | quote('привет мир') → %D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80 |
| Java | URLEncoder.encode | URLEncoder.encode("привет мир", "UTF-8") → %D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82+%D0%BC%D0%B8%D1%80 |
3.2 Экранирование в контексте SQL
Если «гадалка» сохраняет запросы в базе данных, необходимо дополнительно защищаться от SQL‑инъекций. Лучший способ – использовать подготовленные запросы (prepared statements). Если это невозможно, применяйте функции экранирования, предоставляемые драйвером:
- PHP:
mysqli_real_escape_stringили PDO‑плейсхолдеры. - Python (psycopg2, MySQLdb): параметризованные запросы через
%sи передачу параметров отдельным аргументом. - Node.js (mysql2):
connection.escapeили параметры в массиве.
Если ответ от «гадалки» выводится в браузер, убедитесь, что любые пользовательские данные проходят через HTML‑энкодинг:
- JavaScript: создание текстового узла
document.createTextNodeвместо вставки строки вinnerHTML.
Пошаговый пример формирования запроса к API «Гадалка»
4.1 Сценарий
Пользователь вводит вопрос и своё имя. Нужно отправить GET‑запрос:
https://api.gadalki.ru/predict?name=ИМЯ&question=ВОПРОС
4.2 Реализация на PHP
<?php
$name = $_GET['name'] ?? '';
$question = $_GET['question'] ?? '';
/* 1️⃣ Экранируем для URL /
$encName = urlencode($name); // или rawurlencode
$encQuestion = urlencode($question);
/ 2️⃣ Формируем полный URL /
$url = "https://api.gadalki.ru/predict?name={$encName}&question={$encQuestion}";
/ 3️⃣ Выполняем запрос (cURL) /
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo '<pre>' . htmlspecialchars($response, ENT_QUOTES, 'UTF-8') . '</pre>';
?>
4.3 Реализация на JavaScript (fetch)
const name = prompt('Введите ваше имя:');
const question = prompt('Задайте вопрос:');
/* Экранируем параметры */
const params = new URLSearchParams({
name: name,
question: question
});
fetch(`https://api.gadalki.ru/predict?${params.toString}`)
.then(r => r.text)
.then(text => {
// безопасный вывод в DOM
const pre = document.createElement('pre');
pre.textContent = text; // textContent автоматически экранирует
document.body.appendChild(pre);
})
.catch(err => console.error('Ошибка:', err));
Лучшие практики
- Всегда используйте готовые функции. Ручное составление
%XXприводит к ошибкам. - Не смешивайте кодировки. Приводите все строки к UTF‑8 до экранирования.
- Применяйте параметризованные запросы при работе с базами данных.
- Проверяйте длину и тип входных данных. Ограничения снижают риск атак.
- Тестируйте. Используйте инструменты вроде Postman или
curlс различными спецсимволами. - Логи и мониторинг. Записывайте запросы, но без чувствительных данных.
Часто задаваемые вопросы
6.1 Что делать, если сервер «Гадалки» требует application/x-www-form-urlencoded?
Тогда вместо encodeURIComponent используйте URLSearchParams (JS) или http_build_query (PHP). Эти функции автоматически заменяют пробелы на «+» и кодируют остальные символы.
6.2 Как обрабатывать символ «+» в запросе?
В контексте URL‑энкодинга «+» обычно представляет пробел. Если вам нужен именно знак «+», его следует экранировать как %2B.
6.3 Можно ли полностью избавиться от экранирования, используя только POST‑запрос?
POST‑запросы передают данные в теле, но если тело формируется в формате application/x-www-form-urlencoded или multipart/form-data, всё равно требуется кодировать специальные символы. Лучшее решение – использовать application/json и отправлять JSON‑объект, где специальные символы не требуют URL‑энкодинга.
Помните: правильное экранирование – ваш первый щит против большинства веб‑угроз.