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


81

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

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

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

Ответы:


70

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

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

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

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

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

Из документации Google Page Speed :

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

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

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

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

12
Эти менее известные коды состояния HTTP (203, 204, 205) действительно золотые. Они должны увидеть больше пользы, чем сейчас.
You

1
хороший - информация, которую я могу использовать, на самом деле. +1 от меня.
doug

1
позвольте мне посмотреть, смогу ли я подвести итог - подход кода HTTP-ответа включает тот же клиентский запрос; единственная разница в том, что сервер вместо того, чтобы возвращать 1x1 gif (и, я полагаю, 200), вместо этого возвращает 204 обратно клиенту?
doug

2
Но как бы вы запросили то, что возвращает код ответа 204?
Юрген Пауль

3
Я не понимаю, почему имидж. Почему бы не вернуть пустую строку?
Weishi Zeng

65

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

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

Самый простой из методов, описанных протоколом, самый простой (по крайней мере, самый простой метод, который включает тело запроса) - это запрос GET . Согласно этому методу протокола, клиенты инициируют запросы к серверам на ресурсы; серверы обрабатывают эти запросы и возвращают соответствующие ответы.

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

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

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

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

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

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

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

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

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

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

Я использовал браузер Safari, поэтому я щелкнул « Разработать» в строке меню, а затем « Показать веб-инспектор» . В верхней строке Web Inspector щелкните " Ресурсы" , найдите и щелкните ресурс 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 для обозначения разрешения экрана клиента, для меня это значение 1280x800; utmfl - это имя переменной для версии flash, которая имеет значение 10,3 и т. д.

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

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


3
@doug Замечательный ответ. Хотел бы я написать это :) Возможно, стоит добавить заметку о возможности использования HTTP Status Code 204для ответа. См. Это: code.google.com/speed/page-speed/docs/rtt.html Я никогда не пробовал, но теоретически он должен служить той же цели, не требуя передачи самого gif. var i=new Image(); i.src = "http://sharedcount.com/test/beacon.gif";является примером, но я не уверен, что это вызовет какие-либо проблемы с браузером.
Yahel

9
Это не худший ответ, потому что это не ответ :) Я спросил, зачем вообще использовать изображение в формате GIF, поскольку необходимые данные уже были отправлены с запросом.
Viliam

2
Я не хочу быть слишком негативным, извините. Это хорошее объяснение веб-ошибки. Но зачем возвращать данные GIF?
Viliam

@yahelc: это здорово. Считайте это добавлением ответа для других. В качестве комментария это почти не видно.
Viliam

@Villiam, конечно, только что добавил.
Yahel

14

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

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


1
Причина, по которой аналитические приложения (например, Google Analytics, Yahoo Analytics, Omniture и др.) размещают на веб-странице изображение в формате GIF размером 1x1 пиксель, абсолютно не имеет ничего общего с «отладкой» приложения.
doug

3
@doug - Я думаю, что mru указывает здесь на то, что если вы намеренно возвращаете коды ошибок, вы должны различать «истинные» коды ошибок и коды ошибок, которые вы хотели вернуть. Итак, мораль этой истории заключается в том, что никогда не возвращайте код ошибки в результате, если этот результат соответствует задуманному.
Му

3
Я сомневаюсь, что ответ об ошибке будет больше, чем изображение в формате GIF - обратите внимание, что ответ 200 OK также отправляется с изображением в формате GIF.
Viliam

2
@Villiam в большинстве сред не только возвращает код ошибки, но и красиво оформленную html-страницу, описывающую ошибку / предоставляющую дополнительную информацию.
Ulrich Dangel

8

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

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

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


1
в вашем ответе ничего не говорится о цели обслуживания ресурса, т. е. зачем вообще нужно обслуживать ресурс? Ваш ответ направлен на вопрос «Зачем использовать 1x1 gif вместо другого формата изображения? Это тривиальный вопрос с тривиальным ответом (т.е. формат gif имеет меньший размер на попиксельной основе, чем jpeg, png , tiff и т. д.)
doug

Вы можете вызвать загрузку GIF с помощью объекта Javascript Image. Он не будет сообщать пользователю о каких-либо ошибках.
Viliam

@Villiam Действительно возвращая изображение, вы также можете отслеживать браузеры без включенного javascript, просто вставьте тег изображения, <noscript>и он будет работать. И вам не нужно будет ничего делать на стороне сервера, чтобы различать запросы через js (возвращение ошибки) и запросы напрямую через элементы в DOM (возвращение изображения)
Ульрих Дангель

4

Это ответ на вопрос ОП - «зачем использовать данные изображения в формате GIF ...»

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

<img src="http://www.example.com/logger?event_id=1234">

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

Я ищу поле заголовка " Принять" . Когда ваш скрипт вызывается через тег img, подобный этому, в заголовке запроса вы увидите что-то вроде следующего:

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

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


2

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


0

Вам не нужно показывать изображение, если вы используете Beacon API ( https://w3c.github.io/beacon/ метод реализации ).

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


0

@Maciej Perliński в основном прав, но я считаю, что подробный ответ будет полезным.

почему 1x1 GIF, а не 204 No-Contentкод статуса?

204 No-Content позволяет серверу опускать все заголовки ответа (Content-Type, Content-Length, Content-Encoding, Cache-Control и т. д.) и возвращать пустое тело ответа с 0 байтами (и экономить много ненужной полосы пропускания).

Браузеры знают, что нужно уважать 204 No-Contentответы, а не ожидать / ждать заголовков и тела ответа.

если серверу нужно установить какой-либо заголовок ответа (например, cache-controlили cookie), он не может использовать, 204 No-Contentпотому что браузеры будут игнорировать любой заголовок ответа по дизайну (в соответствии со спецификацией протокола HTTP).

почему 1x1 GIF, а не Content-Length: 0заголовок с 200 OKкодом статуса?

Вероятно, это сочетание нескольких проблем, и это лишь некоторые из них:

  • совместимость с устаревшими браузерами
  • Проверка типа MIME в браузерах, 0 байт не является допустимым изображением.
  • 200 OK с 0 байтами может не полностью поддерживаться промежуточными прокси-серверами и VPN
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.