Найти в Дзене

Работа с параметрами запроса в URL, с примером из реальной практики.

Оглавление

В статье разберем что такое параметры запроса, познакомимся 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>

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