Po co w ogóle udostępniać dane w formacie GIF o rozmiarze 1 x 1 piksela (błędów internetowych)?

81

Wiele narzędzi analitycznych i śledzących żąda obrazu 1x1 GIF (błąd sieciowy, niewidoczny dla użytkownika) w celu przechowywania / przetwarzania zdarzeń międzydomenowych.

Po co w ogóle podawać ten obraz GIF? Czy nie byłoby bardziej wydajne, aby po prostu zwrócić kod błędu, taki jak 503 Usługa tymczasowo niedostępna lub pusty plik?

Aktualizacja: Aby było jasne, pytam, dlaczego należy udostępniać dane obrazu GIF, skoro wszystkie wymagane informacje zostały już przesłane w nagłówkach żądań. Sam obraz GIF nie zwraca żadnych przydatnych informacji.

Viliam
źródło

Odpowiedzi:

70

Odpowiedź Douga jest dość wyczerpująca; Pomyślałem, że dodam dodatkową uwagę (na prośbę OP, z mojego komentarza)

Odpowiedź Douga wyjaśnia, dlaczego piksele 1x1 są używane zgodnie z ich przeznaczeniem; Pomyślałem, że nakreślę potencjalne alternatywne podejście, które polega na użyciu kodu stanu HTTP 204, brak treści, do odpowiedzi, a nie wysyłanie treści obrazu.

204 Brak treści

Serwer spełnił żądanie, ale nie musi zwracać treści encji i może chcieć zwrócić zaktualizowane metainformacje. Odpowiedź MOŻE zawierać nowe lub zaktualizowane metainformacje w postaci nagłówków encji, które, jeśli są obecne, POWINNY być skojarzone z żądanym wariantem.

Zasadniczo serwer odbiera żądanie i decyduje się nie wysyłać treści (w tym przypadku nie wysyła obrazu). Ale odpowiada kodem informującym agenta, że ​​była to świadoma decyzja; w zasadzie to tylko krótszy sposób na odpowiedź twierdzącą.

Z dokumentacji Google Page Speed :

Jednym z popularnych sposobów rejestrowania odsłon strony w sposób asynchroniczny jest dołączenie fragmentu kodu JavaScript u dołu strony docelowej (lub jako modułu obsługi zdarzeń onload), który powiadamia serwer rejestrujący o załadowaniu strony przez użytkownika. Najczęstszym sposobem wykonania tego jest skonstruowanie żądania wysyłanego do serwera o „beacon” i zakodowanie wszystkich interesujących danych jako parametrów w adresie URL zasobu beacon. Aby odpowiedź HTTP była bardzo mała, przezroczysty obraz 1 x 1 piksel jest dobrym kandydatem do żądania sygnału nawigacyjnego. Nieco bardziej optymalny sygnał nawigacyjny używałby odpowiedzi HTTP 204 („brak treści”), która jest minimalnie mniejsza niż plik GIF 1x1.

Nigdy tego nie próbowałem, ale teoretycznie powinien służyć temu samemu celowi bez konieczności przesyłania samego gif, oszczędzając 35 bajtów w przypadku Google Analytics. (W schemacie rzeczy, chyba że Google Analytics obsługuje wiele bilionów odwiedzin dziennie, 35 bajtów to naprawdę nic).

Możesz to przetestować za pomocą tego kodu:

var i = new Image(); 
i.src = "http://httpstat.us/204";
Yahel
źródło
12
Te mniej znane kody stanu HTTP (203, 204, 205) są naprawdę złote. Powinni widzieć więcej pożytku niż obecnie.
Ty
1
niezły - faktycznie informacje, które mogę wykorzystać. +1 ode mnie.
Doug
1
zobaczę, czy mogę podsumować - podejście do kodu odpowiedzi HTTP obejmuje to samo żądanie klienta; jedyną różnicą jest to, że serwer, zamiast zwracać gif 1x1 (i przypuszczam, że 200), zwraca 204 z powrotem do klienta?
Doug,
2
Jak jednak poprosiłbyś o to, co zwraca kod odpowiedzi 204?
Jürgen Paul
3
Nie rozumiem, dlaczego obraz. Dlaczego nie zwrócić pustego ciągu?
Weishi Zeng
65

Po pierwsze, nie zgadzam się z dwiema poprzednimi odpowiedziami - żadna z nich nie angażuje pytania.

Obraz jednopikselowy rozwiązuje nieodłączny problem aplikacji analitycznych opartych na sieci (takich jak Google Analytics) podczas pracy w protokole HTTP - jak przesyłać dane (metryki sieciowe) z klienta na serwer .

Najprostszą z metod opisanych w protokole, najprostszą (przynajmniej najprostszą metodą zawierającą treść żądania) jest żądanie GET . Zgodnie z tym protokołem klienci wysyłają do serwerów żądania zasobów; serwery przetwarzają te żądania i zwracają odpowiednie odpowiedzi.

W przypadku internetowej aplikacji analitycznej, takiej jak GA, ten jednokierunkowy schemat to zła wiadomość, ponieważ nie wydaje się, aby serwer mógł pobierać dane od klienta na żądanie - znowu wszystko, co mogą zrobić serwery, to dostarczać zasoby, a nie poproś ich.

Jakie jest więc rozwiązanie problemu pobierania danych od klienta z powrotem na serwer? W kontekście HTTP istnieją inne metody protokołu inne niż GET (np. POST), ale jest to ograniczona opcja z wielu powodów (o czym świadczy jej rzadkie i wyspecjalizowane użycie, takie jak przesyłanie danych formularza).

Jeśli spojrzysz na żądanie GET z przeglądarki, zobaczysz, że składa się ono z adresu URL żądania i nagłówków żądań (np. Referer i User-Agent Headers), te ostatnie zawierają informacje o kliencie - np. Typ przeglądarki i wersja, język przeglądarki, system operacyjny itp.

Ponownie jest to część żądania, które klient wysyła do serwera. Tak więc idea, która motywuje jednopikselowy gif, polega na tym, że klient wysyła dane metryki sieci Web do serwera, zawarte w nagłówku żądania.

Ale w takim razie, jak skłonić klienta do zażądania zasobu, aby można go było „oszukać” w celu przesłania danych metryk? A jak zmusić klienta do wysłania rzeczywistych danych, których potrzebuje serwer?

Dobrym przykładem jest Google Analytics: plik ga.js (duży plik, którego pobieranie do klienta jest uruchamiane przez mały skrypt na stronie internetowej) zawiera kilka wierszy kodu, które kierują klienta do żądania określonego zasobu z określonego serwer (serwer GA) i wysłać pewne dane zawinięte w nagłówku żądania.

Ale ponieważ celem tego żądania nie jest faktyczne uzyskanie zasobu, ale wysłanie danych do serwera, zasób ten powinien być jak najmniejszy i nie powinien być widoczny podczas renderowania na stronie internetowej - stąd 1 x 1 piksel przezroczysty gif. Rozmiar to najmniejszy możliwy rozmiar, a format (gif) to najmniejszy spośród formatów obrazów.

Dokładniej, wszystkie dane GA - każdy pojedynczy element - są składane i pakowane w ciąg zapytania adresu URL żądania (wszystko po znaku „?”). Ale aby te dane zostały przesłane z klienta (gdzie są tworzone) do serwera GA (gdzie są rejestrowane i agregowane), musi istnieć żądanie HTTP, więc ga.js (skrypt Google Analytics jest pobierany, chyba że jest buforowane przez klienta w wyniku funkcji wywoływanej podczas ładowania strony) kieruje klienta do zebrania wszystkich danych analitycznych - np. plików cookie, paska lokalizacji, nagłówków żądań itp. - połączyć je w jeden ciąg i dołącz go jako ciąg zapytania do adresu URL ( * http: //www.google-analytics.com/__utm.gif* ?), a ten stanie się adresem URL żądania .

Łatwo to udowodnić za pomocą dowolnej przeglądarki internetowej, która umożliwia wyświetlenie żądania HTTP dla strony internetowej wyświetlanej w przeglądarce (np. Inspektor sieci Safari , Firefox / Chrome Firebug itp.).

Na przykład wpisałem prawidłowy adres URL do firmowej strony głównej w pasku adresu przeglądarki, co zwróciło tę stronę główną i wyświetliło ją w przeglądarce (mogłem wybrać dowolną witrynę internetową / stronę, która korzysta z jednej z głównych aplikacji analitycznych, GA , Omniture, Coremetrics itp.)

Przeglądarka, której użyłem, to Safari, więc kliknąłem opcję Rozwiń na pasku menu, a następnie Pokaż inspektora sieci . W górnym wierszu Inspektora sieci kliknij opcję Zasoby , znajdź i kliknij zasób utm.gif z listy zasobów wyświetlonej w lewej kolumnie, a następnie kliknij kartę Nagłówki . To pokaże ci coś takiego:

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

Najważniejsze punkty, na które należy zwrócić uwagę, to:

  1. Żądanie było w rzeczywistości żądaniem utm.gif, o czym świadczy pierwszy wiersz powyżej: * Adres URL żądania: http: //www.google-analytics.com/__utm.gif*.

  2. Parametry Google Analytics są wyraźnie widoczne w ciągu zapytania dołączonym do adresu URL żądania : np. Utmsr to nazwa zmiennej GA odnosząca się do rozdzielczości ekranu klienta, w moim przypadku ma wartość 1280x800; utmfl to nazwa zmiennej dla wersji Flash, która ma wartość 10,3 itd.

  3. Nagłówek odpowiedzi o nazwie Content-Type (wysłanej przez plecy serwera do klienta) potwierdza również, że zasób wnioskowane i wrócił był gif piksel 1x1: Content-Type: image / gif

Ten ogólny schemat przesyłania danych między klientem a serwerem istnieje od zawsze; mógłby istnieć lepszy sposób na zrobienie tego, ale jest to jedyny znany mi sposób (który spełnia ograniczenia narzucone przez hostowaną usługę analityczną).

Doug
źródło
3
@doug Fantastyczna odpowiedź. Żałuję, że nie napisałem tego :) Może warto wrzucić notatkę o potencjalnej możliwości wykorzystania HTTP Status Code 204do odpowiedzi. Zobacz to: code.google.com/speed/page-speed/docs/rtt.html Nigdy tego nie próbowałem, ale teoretycznie powinno służyć temu samemu celowi bez konieczności przesyłania samego gifa. var i=new Image(); i.src = "http://sharedcount.com/test/beacon.gif";to przykład, ale nie jestem pewien, czy spowodowałoby to jakiekolwiek problemy z przeglądarką.
Yahel
9
To nie jest najgorsza odpowiedź, ponieważ nie jest odpowiedzią :) Zapytałem, po co w ogóle podawać obraz GIF, skoro wymagane dane zostały już przesłane z żądaniem.
Viliam
2
Nie chcę być zbyt negatywny, przepraszam. To fajne wyjaśnienie błędu internetowego. Ale po co oddawać dane GIF?
Viliam
@yahelc: to świetnie. Rozważ to, aby dodać jako odpowiedź dla innych. Jako komentarz jest prawie niewidoczny.
Viliam,
@Villiam pewnie, właśnie go dodałem.
Yahel,
14

Niektóre przeglądarki mogą wyświetlać ikonę błędu, jeśli nie można załadować zasobu. To sprawia, że ​​debugowanie / monitorowanie usługi jest również trochę bardziej skomplikowane, musisz upewnić się, że Twoje narzędzia monitorujące traktują błąd jako dobry wynik.

OTOH nic nie zyskujesz. Komunikat o błędzie zwracany przez serwer / platformę jest zwykle większy niż obraz 1x1. Oznacza to, że zwiększasz ruch w sieci praktycznie za darmo.

Ulrich Dangel
źródło
1
powód, dla którego aplikacje analityczne (np. Google Analytics, Yahoo Analytics, Omniture itp.) umieszczają na stronie internetowej obraz gif 1 x 1 piksel, nie ma absolutnie nic wspólnego z „debugowaniem” aplikacji.
Doug
3
@doug - Myślę, że mru zwraca uwagę na to, że jeśli celowo zwracasz kody błędów, musisz rozróżniać między „prawdziwymi” kodami błędów i kodami błędów, które zamierzałeś zwrócić. Zatem morał tej historii jest taki, że nigdy nie zwracaj kodu błędu jako wyniku, jeśli wynik jest taki, jaki jest zamierzony.
Moo,
3
Wątpię, czy odpowiedź na błąd byłaby większa niż obraz GIF - zwróć uwagę, że 200 OK jest również odpowiedzią wysłaną z obrazem GIF.
Viliam
2
@Villiam większość środowisk zwraca nie tylko kod błędu, ale także ładnie stylizowaną stronę html opisującą błąd / dostarczającą więcej informacji.
Ulrich Dangel
8

Ponieważ taki GIF ma znaną prezentację w przeglądarce - to pojedynczy piksel, kropka. Cokolwiek innego stwarza ryzyko wizualnej ingerencji w rzeczywistą zawartość strony.

Błędy HTTP mogą pojawiać się jako duże ramki tekstu błędu lub nawet jako wyskakujące okienko. Niektóre przeglądarki mogą również narzekać, jeśli otrzymają puste odpowiedzi.

Ponadto obrazy na stronie są jednym z nielicznych typów danych, które są domyślnie dozwolone we wszystkich przeglądarkach. Cokolwiek innego może wymagać wyraźnego działania użytkownika do pobrania.

thkala
źródło
1
Twoja odpowiedź nie mówi nic o celu służenia zasobowi - tj. dlaczego w ogóle zasób musi być obsługiwany? Twoja odpowiedź jest skierowana na pytanie „po co podawać gif 1 x 1 zamiast innego formatu obrazu? To trywialne pytanie z trywialną odpowiedzią (tj. Format gif ma mniejszy rozmiar na podstawie piksela po pikselu niż jpeg, png , tiff itp.)
doug
Możesz wywołać ładowanie GIF-a za pomocą obiektu Obraz JavaScript. Nie zgłosi żadnych błędów użytkownikowi.
Viliam
@Villiam Naprawdę zwracając obraz, możesz również śledzić przeglądarki bez włączonego javascript, po prostu umieść tag obrazu w <noscript>i będzie działać. I nie trzeba nic robić po stronie serwera, aby odróżnić wniosków za pośrednictwem js (powrót błąd) i wniosków bezpośrednio przez elementy w DOM (powrót obrazu)
Ulrich Dangel
4

To odpowiedź na pytanie OP - „po co udostępniać dane w formacie GIF ...”

Niektórzy użytkownicy umieszczają prosty tag img, aby wywołać usługę rejestrowania zdarzeń -

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

W takim przypadku, jeśli nie wyświetlasz obrazu, przeglądarka wyświetli zastępczą ikonę, która będzie wyglądać brzydko i sprawiać wrażenie, że Twoja usługa jest zepsuta!

Co robię, to poszukaj pola Accept nagłówka. Kiedy twój skrypt jest wywoływany przez taki tag img , zobaczysz coś takiego jak następujący w nagłówku żądania -

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

Gdy w nagłówku Accept znajduje się ciąg „image / ” *, podaję obraz, w przeciwnym razie po prostu odpowiadam za pomocą 204.

Harmeet
źródło
2

Cóż, głównym powodem jest dołączenie do niego pliku cookie, więc jeśli użytkownicy przechodzą z jednej strony na drugą, nadal mamy ten sam element, do którego można dołączyć plik cookie.

Maciej Perliński
źródło
0

Nie musisz udostępniać obrazu, jeśli używasz metody implementacji Beacon API ( https://w3c.github.io/beacon/ ).

Kod błędu zadziała, jeśli masz dostęp do plików dziennika serwera. Celem udostępniania obrazu jest uzyskanie większej ilości danych o użytkowniku niż w przypadku zwykłego pliku dziennika.

fowerizm
źródło
0

@Maciej Perliński jest w zasadzie poprawny, ale uważam, że szczegółowa odpowiedź będzie korzystna.

dlaczego GIF 1x1, a nie 204 No-Contentkod statusu?

204 No-Content umożliwia serwerowi pominięcie wszystkich nagłówków odpowiedzi (Content-Type, Content-Length, Content-Encoding, Cache-Control itp.) i zwrócić pustą treść odpowiedzi z 0 bajtami (i oszczędzając dużo niepotrzebnej przepustowości).

Przeglądarki wiedzą, że należy szanować 204 No-Contentodpowiedzi i nie oczekiwać / czekać na nagłówki odpowiedzi i treść odpowiedzi.

jeśli serwer musi ustawić jakikolwiek nagłówek odpowiedzi (np. cache-controllub cookie), nie może go użyć, 204 No-Contentponieważ przeglądarki będą ignorować dowolny nagłówek odpowiedzi zgodnie z projektem (zgodnie ze specyfikacją protokołu HTTP).

dlaczego 1x1 GIF, a nie Content-Length: 0nagłówek z 200 OKkodem statusu?

Prawdopodobnie jest to mieszanka kilku problemów, żeby wymienić tylko kilka:

  • zgodność ze starszymi przeglądarkami
  • Sprawdzanie typu MIME w przeglądarkach, 0 bajtów nie jest prawidłowym obrazem.
  • 200 OK 0 bajtów może nie być w pełni obsługiwana przez pośredniczące serwery proxy i sieci VPN
Elad Yosifon
źródło