web-dev-qa-db-fra.com

Pourquoi servir des données GIF (bugs Web) 1x1 pixel?

De nombreux outils d'analyse et de suivi demandent une image 1x1 GIF (bug Web, invisible pour l'utilisateur) pour le stockage/traitement d'événements inter-domaines.

Pourquoi servir cette image GIF du tout? Ne serait-ce pas plus efficace renvoyer simplement un code d'erreur tel que 503 Service Temporaire Indisponible ou fichier vide?

Mise à jour: Pour être plus clair, je demande pourquoi servir des données d'image GIF lorsque toutes les informations requises a déjà été envoyé dans les en-têtes de demande. L'image GIF elle-même ne renvoie aucune information utile.

72
Viliam

La réponse de Doug est assez complète. Je pensais ajouter une note supplémentaire (à la demande de l'OP, en dehors de mon commentaire)

La réponse de Doug explique pourquoi les balises de 1x1 pixel sont utilisées aux fins pour lesquelles elles sont utilisées. Je pensais décrire une approche alternative potentielle, qui consiste à utiliser le code d'état HTTP 204, sans contenu, pour la réponse, sans envoyer de corps d'image. 

204 Pas de contenu

Le serveur a répondu à la demande mais n'a pas besoin de retourner un entité-corps, et pourrait vouloir retourner métainformation mis à jour. La réponse PEUT inclure nouveau ou mis à jour métainformation sous la forme de en-têtes d'entité, qui si présents DEVRAIT être associé au variante demandée.

Fondamentalement, le serveur reçoit la demande et décide de ne pas envoyer de corps (dans ce cas, de ne pas envoyer d'image). Mais il répond avec un code pour informer l'agent qu'il s'agissait d'une décision consciente; fondamentalement, c'est juste un moyen plus court de répondre par l'affirmative. 

De Documentation Google Page Speed ​​ :

Une façon populaire d’enregistrer une page les vues de manière asynchrone est to inclure un extrait de code JavaScript dans le fichier bas de la page cible (ou en tant que gestionnaire d'événements onload), qui notifie un serveur de journalisation lorsqu'un utilisateur charge le fichier page. La façon la plus courante de faire il s’agit de construire une requête vers le serveur pour une "balise", et tout encoder les données d'intérêt en tant que paramètres dans l'URL de la ressource balise. À gardez la réponse HTTP très petite, a image transparente de 1x1 pixel est un bon candidat à une demande de balise. UNE balise légèrement plus optimale utiliserait une réponse HTTP 204 ("pas de contenu") qui est légèrement plus petit qu'un 1x1 GIF.

Je ne l'ai jamais essayé, mais en théorie, il devrait servir le même objectif sans exiger que le gif soit transmis, ce qui vous épargne 35 octets, dans le cas de Google Analytics. (Dans l’ordre des choses, à moins que Google Analytics ne traite plusieurs trillions de visites par jour, 35 octets ne représentent en réalité rien.)

Vous pouvez le tester avec ce code:

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

Premièrement, je suis en désaccord avec les deux réponses précédentes - aucune d’entre elles n’engage la question.

L'image d'un pixel résout un problème intrinsèque pour les applications d'analyse basées sur le Web (telles que Google Analytics) lors de l'utilisation du protocole HTTP --comment transférer des données (métriques Web) du client vers le serveur.

La plus simple des méthodes décrites par le protocole, la plus simple (à moins que la méthode la plus simple incluant un corps de requête) soit la requête GET. Selon cette méthode de protocole, les clients initient des demandes de ressources auprès de serveurs; les serveurs traitent ces demandes et renvoient les réponses appropriées.

Pour une application d'analyse basée sur le Web, telle que GA, ce schéma unidirectionnel est une mauvaise nouvelle, car il ne semble pas permettre à un serveur d'extraire des données d'un client à la demande. Encore une fois, tous les serveurs peuvent le faire, mais pas les ressources demandez-les.

Alors, quelle est la solution au problème de la récupération des données du client sur le serveur? Dans le contexte HTTP, il existe d'autres méthodes de protocole que GET (par exemple, POST), mais cette option est limitée pour de nombreuses raisons. (comme en témoigne son utilisation peu fréquente et spécialisée telle que la soumission de données de formulaire).

Si vous examinez une demande GET d'un navigateur, vous constaterez qu'elle est composée d'une URL de demande et En-têtes de demande (par exemple, en-têtes de référent et d'utilisateur-agent), ce dernier contient des informations sur le client - par exemple, type et version du navigateur, langue du navigateur, système d'exploitation, etc.

Là encore, cela fait partie de la demande que le client envoie au serveur. So [L'idée qui motive le gif d'un pixel est que le client envoie les données de métrique Web au serveur, enveloppées dans un en-tête de requête.)

Mais alors comment amener le client à demander une ressource afin qu’elle puisse être "trompée" dans l’envoi des données de métrique? Et comment amener le client à envoyer les données réelles demandées par le serveur?

Google Analytics est un bon exemple: le fichier ga.js (le fichier volumineux dont le téléchargement sur le client est déclenché par un petit script dans la page Web) inclut quelques lignes de code qui demande au client de demander une ressource particulière à un serveur particulier (le serveur GA) et d'envoyer certaines données encapsulées dans l'en-tête de la requête.

Mais puisque le but de cette demande n'est pas d'obtenir réellement une ressource mais d'envoyer des données au serveur, cette ressource doit être aussi petite que possible et ne doit pas être visible lorsqu'elle est restituée dans la page Web - d'où le 1 x 1. pixel transparent gif. La taille est la plus petite possible et le format (gif) est le plus petit parmi les formats d'image.

Plus précisément, toutes les GA données - chaque élément - sont assemblées et regroupées dans le Chaîne de requête de l'URL de requête (tout après le '?' ). Mais pour que ces données puissent passer du client (où elles sont créées) au serveur GA (où elles sont consignées et agrégées), il doit exister une requête HTTP. Le ga.js (google analytics le script téléchargé, sauf mise en cache par le client, suite à une fonction appelée lors du chargement de la page) indique au client d'assembler toutes les données analytiques - par exemple, les cookies, la barre d'emplacement, les en-têtes de requête, etc. - concaténez-le en une seule chaîne et ajoutez-le en tant que chaîne de requête à une URL (* http: //www.google-analytics.com/__utm.gif*?) et cela devient le RL de la demande.

Il est facile de le prouver en utilisant n'importe quel navigateur Web qui vous permet d'afficher la requête HTTP de la page Web affichée dans votre navigateur (par exemple, Safari's Inspecteur Web, Firefox/Chrome Firebug =, etc.).

Par exemple, j'ai tapé une URL valide sur une page d'accueil d'entreprise dans la barre d'emplacement de mon navigateur, qui l'a renvoyée et affichée dans mon navigateur (j'aurais pu choisir n'importe quel site Web/page utilisant l'une des principales applications d'analyse, GA , Omniture, Coremetrics, etc.)

Le navigateur que j’avais utilisé était Safari, c’est pourquoi j’ai cliqué Développer dans la barre de menu, puis Afficher l'inspecteur Web. Sur la rangée supérieure de l'inspecteur Web, cliquez sur Ressources, recherchez la ressource utm.gif dans la liste des ressources affichée dans la colonne de gauche, puis cliquez dessus, puis cliquez sur l'onglet Headers. = onglet. Cela vous montrera quelque chose comme ça:

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

Les points clés à noter sont:

  1. La demande était en fait une demande pour le fichier utm.gif, comme en témoigne la première ligne ci-dessus: * URL de la demande: http: //www.google-analytics.com/__utm.gif*.

  2. Les paramètres de Google Analytics sont clairement visibles dans la chaîne de requête ajoutée à l'URL de la requête: par exemple, tmsr est le nom de la variable de GA qui fait référence à la résolution de l'écran du client. une valeur de 1280x800; tmfl est le nom de la variable pour la version flash, dont la valeur est 10.3, etc.

  3. Le En-tête de réponse appelé Type de conten (renvoyé par le serveur au client) confirme également que la ressource demandée et renvoyée était un gif de 1x1 pixels: - Type de contenu: image/gif

Ce schéma général de transfert de données entre un client et un serveur existe depuis toujours; il pourrait très bien exister un meilleur moyen de le faire, mais c'est le seul moyen que je connaisse (qui réponde aux contraintes imposées par un service d'analyse hébergé).

54
doug

Certains navigateurs peuvent afficher une icône d'erreur si la ressource ne peut pas se charger. Le débogage/surveillance du service est également un peu plus compliqué, vous devez vous assurer que vos outils de surveillance traitent l'erreur comme un bon résultat.

OTOH tu ne gagnes rien. Le message d'erreur renvoyé par le serveur/la structure est généralement plus grand que l'image 1x1. Cela signifie que vous augmentez votre trafic réseau pour pratiquement rien.

13
Ulrich Dangel

Parce qu'un tel GIF a une présentation connue dans un navigateur - c'est un pixel, une période. Tout le reste présente un risque d'interférence visuelle avec le contenu réel de la page. 

Les erreurs HTTP peuvent apparaître sous la forme de cadres de texte d'erreur surdimensionnés ou même d'une fenêtre contextuelle. Certains navigateurs peuvent également se plaindre s'ils reçoivent des réponses vides.

En outre, les images de la page sont l’un des rares types de données autorisés par défaut dans tous les documents. Tout le reste peut nécessiter le téléchargement d'une action explicite de l'utilisateur.

8
thkala

Ceci est pour répondre à la question du PO "Pourquoi servir des données d'image GIF ..."

Certains utilisateurs mettront une simple balise img pour appeler votre service de journalisation des événements -

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

Dans ce cas, si vous ne servez pas d'image, le navigateur affichera une icône d'espace réservé qui aura l'air moche et qui donnera l'impression que votre service est en panne!

Ce que je fais, c'est chercher le champ d'en-tête Accept. Lorsque votre script est appelé via une telle balise img, vous verrez quelque chose comme suit dans l'en-tête de la requête -

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

Quand il y a "image/" * chaîne dans le champ d'en-tête Accept, je fournis l'image, sinon je ne réponds que par 204.

4
Harmeet

La raison principale est d’y attacher le cookie. Ainsi, si les utilisateurs passent d’un côté à l’autre, nous avons toujours le même élément auquel attacher un cookie.

1
Maciej Perliński

@ Maciej Perliński est fondamentalement correct, mais j'estime qu'une réponse détaillée sera bénéfique.

pourquoi 1x1 GIF et pas un code de statut 204 No-Content??

204 No-Content permet au serveur d'omettre tous les en-têtes de réponse (type de contenu, longueur de contenu, codage de contenu, contrôle de cache, etc.) et de renvoyer un corps de réponse vide avec 0 octet (et de sauver beaucoup de choses inutiles). bande passante).

Les navigateurs savent respecter 204 No-Content les réponses et ne pas attendre/attendre les en-têtes et le corps de la réponse.

si le serveur doit définir un en-tête de réponse (par exemple, cache-control ou cookie), il ne peut pas utiliser 204 No-Content, car les navigateurs ignoreront par nature tout en-tête de réponse (conformément à la spécification du protocole HTTP).

pourquoi 1x1 GIF et pas un en-tête Content-Length: 0 avec 200 OK code d'état?

Probablement un mélange de plusieurs problèmes, pour n'en nommer que quelques-uns:

  • compatibilité des anciens navigateurs
  • Le type MIME vérifie les navigateurs, 0 octet n’est pas une image valide.
  • 200 OK avec 0 octet peut ne pas être entièrement pris en charge par les serveurs proxy intermédiaires et les VPN
0
Elad Yosifon

Vous n'avez pas besoin de servir une image si vous utilisez la méthode d'implémentation Beacon API ( https://w3c.github.io/beacon/ ). 

Un code d'erreur fonctionnerait si vous avez accès aux fichiers journaux de votre serveur. L'objectif de la diffusion de l'image est d'obtenir plus de données sur l'utilisateur que vous le feriez normalement avec un fichier journal.

0
fauverism