В статье разберем что такое параметры запроса, познакомимся c так называемыми utm-метками, и научимся работать с параметрами запроса на примере одной ситуации из моей практики.
Начнем с теории.
Внимание! Поскольку статья для начинающих веб-разработчиков, многие понятия в статье даются в упрощенном виде для облегчения понимания.
Параметры запроса
Представим, что есть каталог товаров в интернет-магазине. В каталоге может быть сотни и тысячи наименований товара, и, если выводить их на одной странице, она получится просто огромной, и будет грузится долгое время.
Всем известен выход из этой ситуации: нужно разбить каталог на страницы. Все вы видели такие страницы, там десять или двадцать товаров, а также ссылки на другие страницы каталога.
Как же сформированы подобные ссылки? Вот здесь-то и используются параметры запроса в URL.
Часто параметры запроса называют GET-параметрами. Это не совсем верно. Да, при запросе методом GET, эти параметры видны в строке браузера, но их с тем же успехом можно передавать и POST-запросом.
Посмотрите на адрес:
https://someshop.ru/catalog/iphone?page=1&perpage=20
Здесь:
- https – это протокол, по которому идет передача данных (в данном случае защищенный http);
- someshop.ru – доменное имя хоста (часто просто говорят «домен»);
- catalog/iphone – так называемый «Путь» до конкретной страницы на сайте, часто бывает иерархическим, при этом составные части пути разделяет прямой слэш /;
- page=1&perpage=20 – строка запроса (как раз состоящая из параметров).
Вот именно строку запроса, в большинстве случаев называют GET-параметрами.
Эта строка состоит из пар имя_параметра=значение_параметра.
Пары разделены между собой амперсандом &.
Строка запроса отделена от адреса (с путем) знаком вопроса ?
В адресе выше мы имеем два параметра запроса:
- page со значением 1
- perpage со значением 20
Они означают, что ссылка ведет на 1-ю страницу каталога, и выводить на странице нужно 20 товаров.
UTM-метки
Одним из распространенных примером применением параметров запроса являются так называемые UTM-метки.
UTM-метки – это, по сути, набор параметров запроса с заданными именами.
Они «де-факто» являются стандартом меток для сбора статистики. Практически все системы аналитики, CRM-системы, многочисленные сервисы из самых разных областей, поддерживают работу с UTM-метками.
Имена основных меток:
- utm_source — источник перехода;
- utm_medium — тип трафика;
- utm_campaign — название рекламной кампании;
- utm_content — дополнительная информация по каналу рекламы;
- utm_term — ключевая фраза.
Пример из практики
Я технически поддерживаю один из обучающих проектов.
Имела место следующая ситуация.
- Есть лендинг тренинга, в котором можно участвовать как платно (с расширенными возможностями), так и бесплатно (базовый вариант).
- На этот лендинг «льется трафик» с различных рекламных систем (яндекс.директ, вконтакте, фэйсбук, партнеры…).
- Все рекламные ссылки на этот лендинг размечены utm-метками.
- В свою очередь CRM-система, используемая на проекте, поддерживает работу с UTM-метками и таким образом можно считать выгоду от того или иного канала рекламы, соотнося расходы и продажи по каждому каналу.
- На лендинге имеются 2 ссылки для платного и бесплатного участия. Ссылка для бесплатного участия ведет на отдельную страницу, где находится форма, заполнив которую, человек попадает в группу в CRM для бесплатного участия в тренинге.
Проблема была в том, что при переходе по ссылке на страницу с формой, UTM-метки туда не передавались, и, соответственно, невозможно было понять по какому каналу рекламы пришел человек, который заполнил эту форму.
Формулируем задачу для решения этой проблемы:
нужно взять UTM-метки из строки запроса лендинга и подставить их в ссылку на страницу с формой.
Сделать это нужно было максимально быстро, т.е. «вчера» поскольку на страницу уже шел трафик.
Работа с параметрами запроса на сервере (PHP)
Задача была решена парой строчек кода на PHP.
Ниже код двух страничек, первая это эмуляция лендинга со ссылкой на эмуляцию страницы с формой, вторая это эмуляция страницы с формой.
Вторая страница нужна, чтобы вы могли скопировать ее посмотреть результат перехода по ссылке с лендинга.
Лендинг (index.php):
<?php
$queryStr = filter_input(INPUT_SERVER, 'QUERY_STRING');
$url = $queryStr ? 'form.html?' . $queryStr : 'form.html';
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Лендинг</title>
</head>
<body style="background-color: # f5f5f5">
<div style="width: 100%; max-width: 600px; margin: 100px auto; background-color: # ffffff; padding: 60px 40px; text-align: center;">
<h1>Это лендинг</h1>
<p><a href="<?= $url ?>" target="_blank">Это ссылка на страницу с формой</a></p>
</div>
</body>
</html>
Страница с формой (form.html):
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Страница с формой</title>
</head>
<body style="background-color: # f5f5f5">
<div
style="width: 100%; max-width: 600px; margin: 100px auto; background-color: # ffffff; padding: 60px 40px; text-align: center;">
<h1>Это страница с формой</h1>
</div>
</body>
</html>
Собственно решение в первом PHP-блоке:
<?php
$queryStr = filter_input(INPUT_SERVER, 'QUERY_STRING');
$url = $queryStr ? 'form.html?' . $queryStr : 'form.html';
?>
В первой строке, при помощи функции filter_input, получаем строку запроса из суперглобального массива $_SERVER.
Во второй строке, если строка запроса имеется, прикрепляем её к URL страницы с формой.
Получившуюся переменную $url выводим в атрибуте href ссылки.
Таким образом на страницу form.html стали передаваться UTM-метки, и CRM-система начала получать информацию о канале рекламы, с которого пришел тот или иной посетитель.
Решение, приведенное выше, далеко не универсально. Поскольку берутся все параметры запроса, а кроме UTM-меток, среди них, могут быть и другие параметры.
Стоит немного усовершенствовать код, чтобы брать только те параметры, которые нам нужны.
<?php
$validParams = [ // Допустимые имена параметров
'utm_source',
'utm_medium',
'utm_campaign',
'utm_content',
'utm_term'
];
$queryStr = '';
$inputArray = filter_input_array(INPUT_GET); // Получаем параметры из массива $_GET
if ($inputArray)
{
foreach ($inputArray as $key => $value)
{
$key = strtolower($key);
if(in_array($key, $validParams)) // Проверка имени параметра на допустимость
{
$queryStr .= "$key=$value&"; // В цикле формируем строку с параметрами
}
}
$queryStr = rtrim($queryStr, '&'); //удаляем последний символ &
}
$url = $queryStr ? 'form.html?' . $queryStr : 'form.html';
?>
Работа с параметрами запроса на клиенте (Javascript)
Кроме серверного варианта, существует возможность решить данную задачу на стороне клиента, т.е. через javascript.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Лендинг</title>
</head>
<body style="background-color: # f5f5f5">
<div style="width: 100%; max-width: 600px; margin: 100px auto; background-color: # ffffff; padding: 60px 40px; text-align: center;">
<h1>Это лендинг</h1>
<p><a href="form.html" target="_blank">Это ссылка на страницу с формой</a></p>
</div>
<script>
// Допустимые имена параметров
validParams = [
'utm_source',
'utm_medium',
'utm_campaign',
'utm_content',
'utm_term'
];
// - получаем строку с параметрами запроса и берем подстроку без первого символа "?"
// - преобразуем строку в массив, разбивая ее по символу "&"
const params = window.location.search.substring(1).split('&');
// пропускаем массив через фильтр, в выходном массиве будут параметры с допустимыми именами
const filteredParams = params.filter((item) => {
[name] = item.split('='); //деструктуризацию используем
return validParams.includes(name);
});
// если в отфильтрованном массиве есть элементы
if (filteredParams.length) {
// склеиваем массив в строку параметров, через символ "&"
const paramStr = filteredParams.join('&');
// получаем все ссылки на странице
const links = document.querySelectorAll('a');
// проходимся по полученным ссылкам в цикле
links.forEach((item) => {
// получаем значение атрибута href
const href = item.getAttribute('href');
// если в строке уже есть символ "?", то разделителем делаем "&", иначе разделитель "?"
const separator = href.includes('?') ? '&' : '?';
// устанавливаем новое значение атрибута href
item.setAttribute('href', href + separator + paramStr);
});
}
</script>
</body>
</html>
На мой взгляд, решение на стороне сервера предпочтительнее, хотя бы по причине того, что не зависит от устройства, на котором просматривается страница.