¿Por qué publicar datos GIF (errores web) de 1x1 píxeles?

81

Muchas herramientas analíticas y de seguimiento solicitan una imagen GIF 1x1 (error web, invisible para el usuario) para el almacenamiento / procesamiento de eventos entre dominios.

¿Por qué servir esta imagen GIF? ¿No sería más eficiente simplemente devolver algún código de error como 503 Servicio no disponible temporalmente o archivo vacío?

Actualización: para ser más claro, pregunto por qué entregar datos de imágenes GIF cuando toda la información requerida ya se envió en los encabezados de las solicitudes. La imagen GIF en sí no devuelve ninguna información útil.

Viliam
fuente

Respuestas:

70

La respuesta de Doug es bastante completa; Pensé en agregar una nota adicional (a pedido del OP, fuera de mi comentario)

La respuesta de Doug explica por qué las balizas de 1x1 píxeles se utilizan para el propósito para el que se utilizan; Pensé en esbozar un enfoque alternativo potencial, que es usar el código de estado HTTP 204, sin contenido, para una respuesta y no enviar un cuerpo de imagen.

204 Sin contenido

El servidor ha cumplido con la solicitud, pero no necesita devolver un cuerpo de entidad y es posible que desee devolver metainformación actualizada. La respuesta PUEDE incluir metainformación nueva o actualizada en forma de encabezados de entidad, que si están presentes DEBERÍAN estar asociados con la variante solicitada.

Básicamente, el servidor recibe la solicitud y decide no enviar un cuerpo (en este caso, no enviar una imagen). Pero responde con un código para informar al agente que fue una decisión consciente; básicamente, es solo una forma más corta de responder afirmativamente.

De la documentación de Page Speed ​​de Google :

Una forma popular de registrar las visitas a la página de forma asincrónica es incluir un fragmento de JavaScript en la parte inferior de la página de destino (o como un controlador de eventos de carga), que notifica al servidor de registro cuando un usuario carga la página. La forma más común de hacer esto es construir una solicitud al servidor de una "baliza" y codificar todos los datos de interés como parámetros en la URL del recurso baliza. Para mantener la respuesta HTTP muy pequeña, una imagen transparente de 1x1 píxeles es un buen candidato para una solicitud de baliza. Una baliza ligeramente más óptima usaría una respuesta HTTP 204 ("sin contenido") que es ligeramente más pequeña que un GIF 1x1.

Nunca lo he probado, pero en teoría debería servir para el mismo propósito sin requerir la transmisión del gif en sí, ahorrándote 35 bytes, en el caso de Google Analytics. (En el esquema de las cosas, a menos que Google Analytics proporcione muchos billones de visitas por día, 35 bytes no es realmente nada).

Puedes probarlo con este código:

var i = new Image(); 
i.src = "http://httpstat.us/204";
Yahel
fuente
12
Estos códigos de estado HTTP menos conocidos (203, 204, 205) son realmente oro. Deberían ver más uso que en la actualidad.
Usted
1
buena: información que puedo poner en práctica, de hecho. +1 de mi parte.
doug
1
déjame ver si puedo resumir: el enfoque del código de respuesta HTTP implica la misma solicitud del cliente; la única diferencia es que el servidor, en lugar de devolver el gif 1x1 (y un 200, supongo), devuelve un 204 al cliente.
doug
2
Sin embargo, ¿cómo solicitaría esa cosa que devuelve un código de respuesta 204?
Jürgen Paul
3
No entiendo por qué imagen. ¿Por qué no devolver una cadena vacía?
Weishi Zeng
65

Primero, no estoy de acuerdo con las dos respuestas anteriores, ninguna de las cuales aborda la pregunta.

La imagen de un píxel resuelve un problema intrínseco para las aplicaciones de análisis basadas en la web (como Google Analytics) cuando se trabaja en el protocolo HTTP: cómo transferir datos (métricas web) del cliente al servidor .

El más simple de los métodos descritos por el Protocolo, el más simple (al menos el método más simple que incluye un cuerpo de solicitud) es la solicitud GET . De acuerdo con este método de protocolo, los clientes inician solicitudes de recursos a los servidores; Los servidores procesan esas solicitudes y devuelven las respuestas adecuadas.

Para una aplicación de análisis basada en web, como GA, este esquema unidireccional es una mala noticia, porque no parece permitir que un servidor recupere datos de un cliente a pedido; nuevamente, todo lo que los servidores pueden hacer es suministrar recursos, no solicítelos.

Entonces, ¿cuál es la solución al problema de devolver los datos del cliente al servidor? Dentro del contexto HTTP, existen otros métodos de protocolo además de GET (por ejemplo, POST), pero esa es una opción limitada por muchas razones (como lo demuestra su uso poco frecuente y especializado, como enviar datos de formularios).

Si observa una solicitud GET desde un navegador, verá que está compuesta por una URL de solicitud y encabezados de solicitud (por ejemplo, encabezados de Referer y User-Agent), este último contiene información sobre el cliente, por ejemplo, tipo de navegador y versión, idioma del navegador, sistema operativo, etc.

Nuevamente, esto es parte de la Solicitud que el cliente envía al servidor. Entonces, la idea que motiva el gif de un píxel es que el cliente envíe los datos de métricas web al servidor, dentro de un encabezado de solicitud.

Pero entonces, ¿cómo hacer que el cliente solicite un recurso para que pueda ser "engañado" para que envíe los datos de las métricas? ¿Y cómo conseguir que el cliente envíe los datos reales que desea el servidor?

Google Analytics es un buen ejemplo: el archivo ga.js (el archivo grande cuya descarga en el cliente se activa mediante un pequeño script en la página web) incluye algunas líneas de código que dirigen al cliente a solicitar un recurso en particular de un servidor (el servidor GA) y enviar ciertos datos incluidos en el encabezado de solicitud.

Pero dado que el propósito de esta solicitud no es realmente obtener un recurso sino enviar datos al servidor, este recurso debe ser lo más pequeño posible y no debe ser visible cuando se representa en la página web, por lo tanto, el 1 x 1 gif transparente de píxeles. El tamaño es el más pequeño posible y el formato (gif) es el más pequeño entre los formatos de imagen.

Más precisamente, todos los datos de GA, cada elemento individual, se ensamblan y empaquetan en la cadena de consulta de la URL de solicitud (todo lo que sigue a "?"). Pero para que esos datos vayan del cliente (donde se crea) al servidor GA (donde se registra y se agrega) debe haber una solicitud HTTP, por lo que el ga.js (script de Google Analytics que se descarga, a menos que sea almacenado en caché, por el cliente, como resultado de una función llamada cuando se carga la página) indica al cliente que reúna todos los datos analíticos, por ejemplo, cookies, barra de ubicación, encabezados de solicitud, etc., que los concatene en una sola cadena y agregarlo como una cadena de consulta a una URL ( * http: //www.google-analytics.com/__utm.gif* ?) y esa se convierte en la URL de solicitud .

Es fácil probar esto usando cualquier navegador web que le permita ver la solicitud HTTP para la página web que se muestra en su navegador (por ejemplo, el inspector web de Safari , Firefox / Chrome Firebug , etc.).

Por ejemplo, escribí una URL válida para una página de inicio corporativa en la barra de ubicación de mi navegador, que devolvió esa página de inicio y la mostró en mi navegador (podría haber elegido cualquier sitio web / página que use una de las principales aplicaciones de análisis, GA , Omniture, Coremetrics, etc.)

El navegador que usé fue Safari, así que hice clic en Desarrollar en la barra de menú y luego en Mostrar Inspector web . En la fila superior del Inspector web, haga clic en Recursos , busque y haga clic en el recurso utm.gif de la lista de recursos que se muestra en la columna de la izquierda, luego haga clic en la pestaña Encabezados . Eso te mostrará algo como esto:

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

Los puntos clave a tener en cuenta son:

  1. De hecho, la Solicitud era una solicitud para utm.gif, como lo demuestra la primera línea anterior: * URL de solicitud: http: //www.google-analytics.com/__utm.gif*.

  2. Los parámetros de Google Analytics son claramente visibles en la cadena de consulta adjunta a la URL de la solicitud : por ejemplo, utmsr es el nombre de la variable de GA para referirse a la resolución de pantalla del cliente, para mí, muestra un valor de 1280x800; utmfl es el nombre de la variable para la versión flash, que tiene un valor de 10,3, etc.

  3. El encabezado de respuesta llamado Content-Type (enviado por el servidor al cliente) también confirma que el recurso solicitado y devuelto era un gif de 1x1 píxeles: Content-Type: image / gif

Este esquema general para transferir datos entre un cliente y un servidor ha existido desde siempre; Bien podría haber una mejor manera de hacer esto, pero es la única forma que conozco (que satisface las limitaciones impuestas por un servicio de análisis alojado).

doug
fuente
3
@doug Respuesta fabulosa. Ojalá lo hubiera escrito :) Valdría la pena incluir una nota sobre la posibilidad de usarlo HTTP Status Code 204como respuesta. Vea esto: code.google.com/speed/page-speed/docs/rtt.html Nunca lo he probado, pero en teoría debería servir para el mismo propósito sin requerir la transmisión del gif. var i=new Image(); i.src = "http://sharedcount.com/test/beacon.gif";es un ejemplo, pero no estoy seguro de si presentaría algún problema con el navegador.
Yahel
9
Esta no es la peor respuesta porque no es la respuesta :) Pregunté por qué servir la imagen GIF, ya que los datos requeridos ya se enviaron con la solicitud.
Viliam
2
No quiero ser demasiado negativo, lo siento. Esta es una buena explicación del error web. Pero, ¿por qué devolver los datos GIF?
Viliam
@yahelc: eso es genial. Considérelo para agregar como una respuesta para otros. Como comentario, es casi invisible.
Viliam
@Villiam seguro, lo acabo de agregar.
Yahel
14

Algunos navegadores pueden mostrar un icono de error si el recurso no se pudo cargar. También hace que la depuración / monitoreo del servicio sea un poco más complicado, debe asegurarse de que sus herramientas de monitoreo traten el error como un buen resultado.

OTOH no ganas nada. El mensaje de error devuelto por el servidor / marco suele ser más grande que la imagen 1x1. Esto significa que aumenta el tráfico de su red básicamente por nada.

Ulrich Dangel
fuente
1
la razón por la que las aplicaciones de análisis (por ejemplo, Google Analytics, Yahoo Analytics, Omniture, et al.) colocan una imagen gif de 1x1 píxeles en la página web no tiene absolutamente nada que ver con la "depuración" de la aplicación.
doug
3
@doug - Creo que el punto que mru está haciendo es que si devuelve deliberadamente códigos de error, entonces debe diferenciar entre códigos de error "verdaderos" y códigos de error que pretendía devolver. Entonces, la moraleja de la historia es, nunca devuelva un código de error como resultado cuando ese resultado es el que se pretende.
Moo
3
Dudo que la respuesta de error sea más grande que la imagen GIF; tenga en cuenta que 200 OK es la respuesta también enviada con la imagen GIF.
Viliam
2
@Villiam la mayoría de los entornos no solo devuelven el código de error, sino también una página html con un estilo agradable que describe el error y proporciona más información.
Ulrich Dangel
8

Debido a que dicho GIF tiene una presentación conocida en un navegador, es un solo píxel, punto. Cualquier otra cosa presenta el riesgo de interferir visualmente con el contenido real de la página.

Los errores HTTP pueden aparecer como marcos de texto de error de gran tamaño o incluso como una ventana emergente. Algunos navegadores también pueden quejarse si reciben respuestas vacías.

Además, las imágenes en la página son uno de los pocos tipos de datos permitidos por defecto en todos los navegadores. Cualquier otra cosa puede requerir la descarga de la acción explícita del usuario.

thkala
fuente
1
su respuesta no dice nada sobre el propósito de servir el recurso, es decir, ¿por qué es necesario servir un recurso? Tu respuesta se dirige a la pregunta "¿por qué publicar un gif de 1x1 en lugar de otro tipo de formato de imagen? Esa es una pregunta trivial con una respuesta trivial (es decir, el formato gif tiene un tamaño más pequeño píxel por píxel que jpeg, png , tiff, etc.)
doug
Puede invocar la carga de GIF con el objeto Imagen de Javascript. No informará ningún error al usuario.
Viliam
@Villiam Devolviendo realmente la imagen, también puede rastrear navegadores sin javascript habilitado, simplemente coloque la etiqueta de la imagen <noscript>y funcionará. Y no tendrá que hacer nada en el lado del servidor para distinguir entre solicitudes a través de js (devolviendo un error) y solicitudes directamente a través de elementos en el DOM (devolviendo una imagen)
Ulrich Dangel
4

Esto es para responder a la pregunta del OP: "por qué servir datos de imágenes GIF ..."

Algunos usuarios colocarán una etiqueta img simple para llamar a su servicio de registro de eventos:

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

En este caso, si no sirve una imagen, el navegador mostrará un icono de marcador de posición que se verá feo y dará la impresión de que su servicio no funciona.

Lo que hago es buscar el campo de encabezado Aceptar . Cuando se llama a su script a través de una etiqueta img como esta, verá algo como seguir en el encabezado de la solicitud:

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

Cuando hay una cadena "image / " * en el campo Aceptar encabezado, proporciono la imagen; de lo contrario, solo respondo con 204.

Harmeet
fuente
2

Bueno, la razón principal es adjuntar la cookie para que, si los usuarios van de un lado a otro, todavía tenemos el mismo elemento para adjuntar la cookie.

Maciej Perliński
fuente
0

No es necesario que sirva una imagen si está utilizando el método de implementación Beacon API ( https://w3c.github.io/beacon/ ).

Un código de error funcionaría si tiene acceso a los archivos de registro de su servidor. El propósito de servir la imagen es obtener más datos sobre el usuario de lo que normalmente obtendría con un archivo de registro.

fauverismo
fuente
0

@Maciej Perliński es básicamente correcto, pero creo que una respuesta detallada será beneficiosa.

¿Por qué 1x1 GIF y no un 204 No-Contentcódigo de estado?

204 No-Content permite al servidor omitir todos los encabezados de respuesta (Content-Type, Content-Length, Content-Encoding, Cache-Control, etc.) y devolver un cuerpo de respuesta vacío con 0 bytes (y ahorrar mucho ancho de banda innecesario).

Los navegadores saben respetar las 204 No-Contentrespuestas y no esperar ni esperar los encabezados y el cuerpo de la respuesta.

si el servidor necesita establecer cualquier encabezado de respuesta (por ejemplo, cache-controlo cookie), no puede usarlo 204 No-Contentporque los navegadores ignorarán cualquier encabezado de respuesta por diseño (de acuerdo con la especificación del protocolo HTTP).

¿Por qué GIF 1x1 y no un Content-Length: 0encabezado con 200 OKcódigo de estado?

Probablemente una combinación de varios problemas, solo por nombrar algunos:

  • compatibilidad con navegadores heredados
  • Verificaciones de tipo MIME en navegadores, 0 bytes no es una imagen válida.
  • 200 OK con 0 bytes puede que no sea totalmente compatible con servidores proxy intermedios y VPN
Elad Yosifon
fuente