Атрибут ping в HTML: как отправить сигнал о клике по ссылке

Атрибут ping заставляет браузер сообщить серверу о клике по ссылке. Пока читатель переходит по адресу из href, браузер отдельно отправляет короткий запрос на адреса, которые вы записали в ping. Его пишут в теге <a> и в теге <area> . Ниже разобрано, что именно уходит на сервер, как принять этот сигнал, почему на него нельзя полагаться как на единственный счётчик и чем он отличается от обычной аналитики.

HTML
<a href="/files/price.pdf" ping="/stat/click">Скачать прайс</a>

Атрибут ping в HTML: что делает и у каких тегов работает

Обычно клик по ссылке видит только следующая страница. Чтобы посчитать клики по ссылкам на чужие сайты или на файлы, раньше ставили на ссылку скрипт или гнали переход через промежуточный адрес. Атрибут ping решает это одной записью в разметке: браузер сам отправит сигнал, а переход пойдёт как обычно. Не путайте с командой ping из Windows, которая проверяет связь с сервером: у атрибута другая задача.

Тег Что делает ping Пример записи
<a> При клике по ссылке отправляет сигнал на указанные адреса<a href="/price.pdf" ping="/stat/click">
<area> То же для области на карте-изображении<area href="/price.pdf" ping="/stat/click" alt="Прайс">
<link> , <button> , <form> Не поддерживают: такого атрибута у них нет<button ping="/stat"> ничего не сделает

Правила записи и поведения описаны в разделе стандарта HTML про отслеживание переходов по ссылкам .

Значение атрибута ping: как записать один адрес или несколько

Значение ping это список адресов через пробел. Адрес может быть относительным, как у href, или полным, и вести даже на другой сайт. Годятся адреса http и https, а ftp, data, blob и javascript браузер пропускает. Пустое значение ничего не отправляет. Если адресов несколько, запрос уйдёт на каждый.

Запись Что произойдёт при клике Пример записи
Один адресОдин запрос на этот адресping="/stat/click"
Несколько адресовПо запросу на каждый адрес из спискаping="/stat/a /stat/b"
Адрес другого сайтаЗапрос уйдёт и туда, поэтому следите, кому доверяетеping="https://stat.example.com/c"
Пустое значениеЗапросов нетping=""

Адреса разделяет только пробел. Запятая и точка с запятой разделителями не считаются, поэтому запись через запятую даст один неправильный адрес.

HTML
<a href="/dest" ping="/ping-a /ping-b /ping-c">...</a>

Пример: сколько запросов уходит при клике

Результат

Нажмите каждую ссылку и посмотрите в списке, какие запросы ушли. Страница читает их через браузер, поэтому в списке то, что браузер отправил на самом деле.

Что отправляет атрибут ping: запрос, заголовки и тело

Сигнал это обычный POST-запрос. Браузер отправляет его во время перехода по ссылке и не показывает читателю ничего: ни ошибок, ни загрузки. Тело запроса всегда одно и то же, слово PING, а полезная информация лежит в заголовках.

HTTP
POST /stat/click HTTP/1.1
Content-Type: text/ping
Ping-From: https://site.ru/catalog.html
Ping-To: https://site.ru/files/price.pdf

PING
Что в запросе Что это значит Пример записи
Ping-FromСтраница, на которой нажали ссылкуhttps://site.ru/catalog.html
Ping-ToАдрес, куда ведёт ссылка (из href)https://site.ru/files/price.pdf
Content-TypeТип тела запроса, обычно text/pingtext/ping
ТелоСлово PING и больше ничегоPING

Набор заголовков может отличаться от браузера к браузеру, поэтому надёжно использовать лишь то, что в запросе есть всегда: сам адрес, на который пришёл POST. Нужные сведения удобно передавать прямо в адресе ping, например номер товара: ping="/stat/click?id=17".

Атрибут ping и счётчик кликов: как принять сигнал на сервере

Принять сигнал может любой сервер, который умеет отвечать на POST. Ответ браузер не читает, поэтому достаточно коротко ответить кодом 204 «без содержимого». Вот минимальный пример на Node.js: он считает клики и записывает адрес, куда вела ссылка.

JS
const http = require("http");
let clicks = 0;

http.createServer((req, res) => {
  if (req.method === "POST" && req.url === "/stat/click") {
    clicks++;
    console.log(clicks, req.headers["ping-to"]);
    res.writeHead(204);
    return res.end();
  }
  res.writeHead(404);
  res.end();
}).listen(3000);

Без своего сервера атрибут бесполезен: сигнал можно отправить, но принимать его некому. На сайте, где нельзя запускать серверный код, например на Blogger, ping принесёт пользу только вместе с адресом внешней службы, которой вы доверяете.

Атрибут ping и браузеры: где он работает, а где выключен

Атрибут описан в стандарте, но его отправка зависит от браузера и его настроек. Сигнал уходит не всегда, и главные причины такие.

Ситуация Что происходит Пример записи
Обычный браузер на компьютереСигнал обычно уходит при кликеping="/stat/click"
Отправка выключена настройкойЗапроса нет, а переход работает. В некоторых браузерах за это отвечает настройка, например browser.send_pingsabout:config
Расширение блокировщикаБлокировщики рекламы и приватности могут резать такие запросыping="/stat/click"
Ссылка без hrefКлика-ссылки нет, значит, и сигнала нет<a ping="/stat">

Поэтому счётчик на ping всегда занижает число кликов. Для точных цифр его сверяют с серверными журналами или другой аналитикой. Актуальную таблицу поддержки смотрите на странице тега a в MDN или на Can I use.

Пример: в каких случаях при клике уходит сигнал

Результат

Нажимайте ссылки и кнопку: список покажет, на каких действиях браузер отправил запрос. Ссылка без href не считается ссылкой, и сигнала от неё не будет.

Сигнал уходит при обычном клике, при открытии в новой вкладке, при скачивании файла и при клике через скрипт link.click(). Этого достаточно, чтобы считать клики по ссылкам на файлы, которые вы раздаёте со своего сайта.

Атрибут ping и приватность: чем он отличается от аналитики

Читатель не видит, что клик отправил сигнал: ни подсказки, ни значка. Поэтому у ping репутация скрытого слежения, и часть блокировщиков отрезает его по умолчанию. Если вы используете атрибут, упомяните сбор статистики на странице о конфиденциальности. Это общее правило, а не юридическая консультация.

Способ Чем отличается Пример записи
pingРаботает без скрипта, но читатель не может его отключить на странице<a ping="/stat">
fetch в обработчике кликаНужен скрипт, зато виден в коде и гибче в настройкахlink.addEventListener("click", ...)
navigator.sendBeaconСкрипт отправляет запрос так, чтобы он не потерялся при уходе со страницыnavigator.sendBeacon("/stat")
Обычная аналитикаСчитает посещения страниц, а не клики по отдельной ссылкеМетрика, GA

Если нужен точный счётчик с гибкой логикой, используйте скрипт. Если нужна лёгкая запись клика на файл или внешнюю ссылку без скрипта, ping подойдёт, пока вы принимаете, что часть кликов потеряется.

Как прочитать и изменить атрибут ping через JavaScript

В JavaScript у ссылки есть свойство ping, строка со списком адресов, как в атрибуте. Если атрибута нет, возвращается пустая строка. Записать новое значение можно присваиванием, а список адресов проще всего разбирать через split.

JS
const link = document.querySelector("a");

link.ping;                      // "" если атрибута нет
link.hasAttribute("ping");      // true или false

link.ping = "/stat/a /stat/b";  // два адреса
link.ping.split(" ");           // ["/stat/a", "/stat/b"]
link.removeAttribute("ping");

Пример: чтение и запись свойства ping

Результат

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

Частые ошибки с атрибутом ping

Почти все проблемы с ping сводятся к ожиданию, что сигнал придёт всегда и в готовом виде. Он приходит не всегда и очень скуп на сведения.

Ошибка Что происходит Как исправить
Считать клики только по pingЧасть сигналов теряется из-за настроек и блокировщиковСверять с серверными журналами или другой аналитикой
Разделить адреса запятой: ping="/a,/b"Получится один неправильный адресРазделять адреса пробелом
Ждать, что ping заменит hrefПереход идёт по href, а ping лишь сообщает о нёмВсегда писать оба атрибута
<a ping> без hrefЭто не ссылка, клик сигнала не отправляетДобавить href
<button ping="/stat">У кнопки такого атрибута нет, ничего не уходитСкрипт или ссылка с ping
Принимать сигнал через GETСервер получит только POST, адрес вернёт ошибкуОбработать метод POST
Отвечать на сигнал длинной страницейОтвет браузер всё равно не читает, зря тратится время сервераОтвечать кодом 204 без содержимого
Прятать сбор статистикиЧитатель не знает, что клики считаютсяНаписать об этом в политике конфиденциальности

Шпаргалка по атрибуту ping

Всё главное об атрибуте ping в одной таблице.

Что Как работает Пример записи
Где пишутУ a и area, при наличии href<a href="/a" ping="/stat">
ЗначениеСписок адресов через пробелping="/stat/a /stat/b"
ЗапросPOST с телом PINGContent-Type: text/ping
ЗаголовкиОткуда нажали и куда ведёт ссылкаPing-From, Ping-To
Когда уходитПри обычном клике, в новой вкладке, при скачивании, при click()link.click()
Ответ сервераБраузер его не читает, хватит 204res.writeHead(204)
НадёжностьСигнал может не дойти: настройки, блокировщикиbrowser.send_pings
JavaScriptlink.ping это строка, пустая, пока атрибута нетlink.ping = "/stat"
Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×