Зачем вообще загружать данные размером 1×1 пиксель GIF (веб-ошибки)?

Многие аналитические и отслеживающие инструменты запрашивают изображение 1×1 GIF (веб-ошибка, невидимая для пользователя) для хранения / обработки событий в междоменном режиме.

Зачем вообще воспроизводить этот образ GIF? Не было бы более эффективным просто вернуть некоторый код ошибки, такой как 503 Service Temporary Unavailable или пустой файл?

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

Ответ Дуга довольно всеобъемлющий; Я думал, что добавлю дополнительную заметку (по просьбе OP, вне моего комментария)

Ответ Дуга объясняет, почему 1×1 пиксельные маяки используются для целей, для которых они используются; Я думал, что я опишу потенциальный альтернативный подход, который должен использовать HTTP-код состояния 204, No Content, для ответа и не отправлять тело изображения.

204 Нет содержимого

Сервер выполнил запрос, но ему не нужно возвращать тело сущности и может захотеть вернуть обновленную метаинформацию. Ответ МОЖЕТ включать новую или обновленную метаинформацию в виде заголовков-сущностей, которые, если они ДОЛЖНЫ быть связаны с запрошенным вариантом.

В принципе, сервер получает запрос и решает не отправлять тело (в этом случае не отправлять изображение). Но он отвечает кодом, чтобы сообщить агенту, что это было сознательное решение; в основном, его просто более короткий способ ответить утвердительно.

Из документации по скорости страницы Google :

Одним из популярных способов записи просмотров страниц в асинхронном режиме является включение fragmentа JavaScript в нижней части целевой страницы (или в качестве обработчика события onload), который уведомляет сервер регистрации, когда пользователь загружает страницу. Наиболее распространенный способ сделать это – построить запрос на сервер для «маяка» и закодировать все данные, представляющие интерес, в качестве параметров в URL-адресе ресурса маякового радиосигнала. Для того чтобы HTTP-ответ был очень мал, прозрачный 1×1-пиксельный образ является хорошим кандидатом для запроса маяка. Несколько более оптимальный маяк будет использовать ответ HTTP 204 («без содержимого»), который немного меньше, чем 1×1 GIF.

Я никогда не пробовал, но теоретически он должен работать с той же целью, не требуя передачи самого gif, сохраняя при этом 35 байт, в случае с Google Analytics. (В схеме вещей, если вы не используете Google Analytics много триллионов обращений в день, 35 байтов на самом деле ничего.)

Вы можете проверить его с помощью этого кода:

var i = new Image(); i.src = "http://httpstat.us/204"; 

Во-первых, я не согласен с двумя предыдущими ответами – не затрагивает вопрос.

Однопиксельное изображение решает внутреннюю проблему для веб-аналитических приложений (например, Google Analytics) при работе в HTTP-протоколе – как передавать (веб-метрики) данные с клиента на сервер .

Простейший из методов, описанных Протоколом, самый простой (по крайней мере, самый простой способ, который включает тело запроса) – это запрос GET . В соответствии с этим методом протокола клиенты инициируют запросы к серверам для ресурсов; серверы обрабатывают эти запросы и возвращают соответствующие ответы.

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

Итак, каково решение проблемы получения данных от клиента на сервер? В контексте HTTP существуют другие методы протокола, отличные от GET (например, POST), но это ограниченный вариант по многим причинам (о чем свидетельствует его редкое и специализированное использование, например, представление данных формы).

Если вы посмотрите на запрос GET в браузере, вы увидите, что он состоит из URL-адреса запроса и заголовков запросов (например, заголовков Referer и User-Agent), последний содержит информацию о клиенте – например, тип браузера и версия, браузер langauge, операционная система и т. д.

Опять же, это часть запроса, который клиент отправляет на сервер. Таким образом, идея, которая мотивирует однопиксельный gif, заключается в том, что клиент отправляет данные веб-метрики на сервер, завернутые в заголовок запроса.

Но тогда как заставить клиента запрашивать ресурс, чтобы его можно было «обмануть» в отправке данных показателей? И как заставить клиента отправлять фактические данные, которые хочет сервер?

Хорошим примером является Google Analytics: файл ga.js (большой файл, загрузка которого клиенту запускается небольшим скриптом на веб-странице) включает несколько строк кода, которые направляют клиента на запрос определенного ресурса от определенного сервер (сервер GA) и отправить определенные данные, завернутые в заголовок запроса.

Но поскольку цель этого Запроса состоит не в том, чтобы фактически получить ресурс, а для отправки данных на сервер, этот ресурс должен быть как можно меньшим, и он не должен быть видимым при визуализации на веб-странице – следовательно, 1 x 1 пиксель прозрачный gif. Размер минимально возможный, а формат (gif) – самый маленький среди форматов изображений.

Точнее, все данные GA – каждый отдельный элемент – собраны и упакованы в строку запроса URL-адреса запроса (все после «?»). Но для того, чтобы эти данные переходили с клиента (где он был создан) на сервер GA (где он регистрировался и агрегировался), должен быть HTTP-запрос, поэтому ga.js (сканер google analytics, который загружен, кэшируется клиентом в результате функции, вызванной при загрузке страницы) направляет клиента на сбор всех данных аналитики – например, куки, панель местоположений, заголовки запросов и т. д. – объединяет их в одну строку и добавьте его как строку запроса в URL-адрес ( * http: //www.google-analytics.com/__utm.gif ??), и это станет URL-адресом запроса .

Это легко доказать с помощью любого веб-браузера, который позволяет вам просматривать HTTP-запрос на веб-страницу, отображаемую в вашем браузере (например, веб-инспектор Safari, Firefox / Chrome Firebug и т. Д.).

Например, я напечатал действительный URL-адрес на домашней странице на домашней странице моего браузера, который вернул эту домашнюю страницу и отобразил ее в моем браузере (я мог выбрать любой веб-сайт / страницу, которая использует одно из основных приложений для аналитики, GA , Omniture, Coremetrics и т. Д.)

В браузере, который я использовал, был Safari, поэтому я нажал кнопку « Развернуть» в строке меню, а затем « Показать веб-инспектор» . В верхней строке веб-инспектора выберите « Ресурсы» , найдите и щелкните ресурс utm.gif из списка ресурсов, указанных в левом столбце, затем перейдите на вкладку « Заголовки ». Это покажет вам что-то вроде этого:

 Request URL:http://www.google-analytics.com/__utm.gif? utmwv=1&utmn=1520570865& utmcs=UTF-8& utmsr=1280x800& utmsc=24-bit& utmul=enus& utmje=1& utmfl=10.3%20r181& Request Method:GET Status Code:200 OK Request Headers User-Agent:Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1 Response Headers Cache-Control:private, no-cache, no-cache=Set-Cookie, proxy-revalidate Content-Length:35 Content-Type:image/gif Date:Wed, 06 Jul 2011 21:31:28 GMT 

Ключевыми моментами, которые следует обратить внимание, являются:

  1. Запрос фактически был запросом utm.gif, о чем свидетельствует первая строка выше: * URL-адрес запроса: http: //www.google-analytics.com/__utm.gif.

  2. Параметры Google Analytics хорошо видны в строке запроса, добавленной к URL-адресу запроса : например, utmsr – это имя переменной GA для обозначения разрешения экрана клиента, для меня – значение 1280×800; utmfl – это имя переменной для флеш-версии, которая имеет значение 10.3 и т. д.

  3. Заголовок ответа, называемый Content-Type (отправленный сервером обратно клиенту), также подтверждает, что запрошенный и возвращенный ресурс был размером 1×1 пиксель gif: Content-Type: image / gif

Эта общая схема передачи данных между клиентом и сервером существует навсегда; вполне может быть лучший способ сделать это, но это единственный способ, которым я знаю (который удовлетворяет ограничениям, наложенным размещенной службой аналитики).

В некоторых браузерах может отображаться значок ошибки, если ресурс не может загрузить. Это делает отладку / мониторинг службы еще более сложной, вы должны убедиться, что ваши средства мониторинга рассматривают ошибку как хороший результат.

OTOH вы ничего не получаете. Сообщение об ошибке, возвращаемое сервером / фреймворком, обычно больше, чем изображение 1×1. Это означает, что вы увеличиваете сетевой трафик, в основном ничего.

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

Ошибки HTTP могут отображаться как негабаритные кадры текста ошибки или даже как всплывающие windows. Некоторые браузеры могут также жаловаться, если они получают пустые ответы.

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

Это должно ответить на вопрос OP – «зачем обслуживать данные изображения GIF …»

Некоторые пользователи помещают простой тег img для вызова службы регистрации событий –

  

В этом случае, если вы не будете показывать изображение, браузер отобразит значок замещающего, который будет выглядеть уродливым и создаст впечатление, что ваш сервис сломан!

Что я делаю, ищите поле заголовка Accept . Когда ваш сценарий вызывается через тег img, как это, вы увидите что-то вроде следующего в заголовке запроса –

 Accept: image/gif, image/* Accept-Encoding:gzip,deflate ... 

Когда в поле заголовка « Принять » есть строка «image / » *, я предоставляю изображение, иначе я просто отвечу 204.

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