2011-07-10 62 views
71

許多分析和跟蹤工具正在請求1x1 GIF圖像(網絡bug,用戶不可見)進行跨域事件存儲/處理。爲什麼要提供1x1像素的GIF(網絡臭蟲)數據呢?

爲什麼要提供這個GIF圖像呢?難道是效率更高僅僅返回一些錯誤代碼,如503服務臨時不可用或空文件?

更新:在請求的頭部更清楚,我問爲什麼要成爲GIF圖像數據時的所有信息所需已經已經發出已。 GIF圖像本身不會返回任何有用的信息。

回答

62

Doug的回答非常全面;我想我會添加一個額外的筆記(在OP的請求,關閉我的評論)

Doug的答案解釋了爲什麼1x1像素信標用於他們的目的;我想我會概述一種潛在的替代方法,即使用HTTP狀態代碼204,無內容作爲響應,而不發送圖像主體。

204無內容

服務器已完成要求 但並不需要返回 實體主體,並且可能要返回 更新的元信息。響應 可能包含新的或更新的 元信息,其形式爲 實體標題,如果存在 應該與 請求的變體相關聯。

基本上,服務器收到請求,並決定不發送一個正文(在這種情況下,不發送圖像)。但它回覆了一個代碼,告知代理人這是一個有意識的決定;基本上,它只是一個較短的方式來回應肯定。

Google's Page Speed documentation

一個以異步方式 觀點記錄頁的流行的方式是 包括在 底部的目標頁面的JavaScript代碼段(或作爲 onload事件處理),在用戶加載 頁面時通知 日誌服務器。這是爲 構建對「信標」的請求,並將所有感興趣的數據編碼爲 信標資源的URL中的參數。至 保持HTTP響應非常小, 透明1x1像素圖像是一個好的 候選人的信標請求。 A 稍微更優的信標將使用 HTTP 204響應(「無內容」) ,其略小於1x1 GIF。

我從來沒有嘗試過它,但理論上它應該服務於相同的目的,而不需要傳輸gif本身,在Google Analytics(分析)的情況下可以節省35個字節。 (在對事物的計劃,除非你是谷歌Analytics(分析)服務,每天點擊率多少萬億,35個字節是沒什麼好說的。)

您可以使用此代碼測試:

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

這些鮮爲人知的HTTP狀態碼(203,204,205)是黃金,真的。他們應該看到比目前更多的用途。 – You

+0

不錯的一個 - 事實上,我可以使用的信息。從我+1。 – doug

+1

讓我看看我能否總結 - HTTP響應代碼方法涉及*相同*客戶端請求;唯一的區別是服務器不是返回1x1 gif(而是200,我想),而是返回204回到客戶端? – doug

12

如果資源無法加載,某些瀏覽器可能會顯示錯誤圖標。它使調試/監控服務也變得更加複雜一些,您必須確保您的監控工具將錯誤視爲良好的結果。

OTOH你什麼也得不到。服務器/框架返回的錯誤消息通常比1x1圖像大。這意味着你增加你的網絡流量幾乎沒有。

+1

分析應用程序(例如Google Analytics,Yahoo Analytics,Omniture等)在網頁上放置1x1像素gif圖像的原因與「調試」應用程序絕對無關。 – doug

+3

@doug - 我認爲mru的意思是說如果你故意返回錯誤代碼,那麼你必須區分「真實」錯誤代碼和你想返回的錯誤代碼。所以故事的寓意是,當結果是預期的時候,從不返回錯誤代碼。 – Moo

+3

我懷疑錯誤響應會比GIF圖片大 - 請注意,200 OK是響應以及GIF圖片發送的。 – Viliam

8

因爲這樣的GIF在瀏覽器中有一個已知的演示文稿 - 它是一個單獨的像素,句點。其他任何內容都會帶來視覺干擾頁面實際內容的風險。

HTTP錯誤可能會顯示爲超大尺寸的錯誤文本框架,甚至可能顯示爲彈出窗口。一些瀏覽器也可能會抱怨,如果他們收到空回覆。

此外,頁內圖像是默認情況下允許在所有broswers中的極少數數據類型之一。其他任何可能都需要明確的用戶操作才能下載。

+1

你的回答沒有提到服務資源的目的 - 即爲什麼資源需要服務?你的回答是針對「爲什麼要提供1x1 gif而不是其他類型的圖像格式?這是一個微不足道的問題,只有一個簡單的答案(即,gif格式在逐個像素的基礎上比jpeg的尺寸更小,png ,tiff等) – doug

+0

您可以使用Javascript Image對象調用GIF加載,它不會向用戶報告任何錯誤 – Viliam

+0

@Villiam通過真正返回圖片,您還可以跟蹤未啓用javascript的瀏覽器,只需將圖片標籤到'

52

首先,我不同意前面的兩個答案 - 既不涉及這個問題。

該一個像素的圖像解決了基於web的應用程序分析的固有問題(如谷歌分析)在HTTP Protocol-- 工作時如何從客戶端傳輸(網絡度量)數據發送到服務器

協議描述的最簡單的方法是最簡單的(最簡單的方法,其中包括一個請求體)是GET請求。根據該協議方法,客戶端向服務器發起資源請求;服務器處理這些請求並返回適當的響應。

對於像GA這樣的基於網絡的分析應用程序,這種單向方案是個壞消息,因爲它似乎不允許服務器按需從客戶端檢索數據 - 所有服務器都可以做到這一點是供應資源而不是要求他們。

那麼,從客戶端獲取數據返回服務器的問題有什麼解決方案?在HTTP上下文中,除了GET之外,還有其他的協議方法(例如POST),但由於許多原因(如其提交表單數據的頻繁和專門用途所證明的),這是有限的選項。

如果你看一下從瀏覽器的GET請求,你會看到它是由一個請求URL和請求頭(例如,Referer和User-Agent Headers),後者包含關於客戶端的信息 - 例如,瀏覽器類型和版本,瀏覽器語言,操作系統等。

同樣,這是客戶端發送到服務器。所以激勵一個像素gif的想法是客戶端將web metrics數據發送到服務器,並將其包裝在請求標頭中。

但是,然後如何讓客戶端請求一個資源,以便它可以「欺騙」發送度量數據?如何讓客戶端發送服務器需要的實際數據?

谷歌Analytics(分析)是一個很好的例子:的ga.js文件(大文件,其下載到客戶端是通過在網頁中的小腳本觸發)包括幾行代碼是指示客戶端從特定服務器(GA服務器)請求特定資源併發送包裝在請求標頭中的某些數據。

但是由於此請求的目的並不是實際獲取資源,而是將數據發送到服務器,因此此資源應該儘可能小,並且在網頁中呈現時應該不可見 - 因此,1 x 1像素透明gif。尺寸是可能的最小尺寸,並且格式(gif)是圖像格式中最小的尺寸。

更確切地說,所有的GA數據 - 每一個項目 - 組裝,包裝到請求URL的查詢字符串(後一切「?」)。但爲了使數據從客戶端(創建它的地方)到GA服務器(它被記錄和聚合的地方),必須有一個HTTP請求,所以ga.js(谷歌分析腳本被下載,除非它是由客戶端緩存,作爲頁面加載時調用的函數的結果)引導客戶端彙集所有分析數據 - 例如,cookie,地址欄,請求標題等 - 將它們連接成單個字符串並將其作爲查詢字符串追加到URL(* http://www.google-analytics.com/zh-CN/imm.gif*?),然後變成請求URL

人們很容易這樣使用具有允許您查看在瀏覽器中顯示的網頁的HTTP請求任何Web瀏覽器來證明(例如,Safari的網絡督察,火狐/鉻螢火蟲等)。

例如,我輸入了一個有效的網址到我的瀏覽器的地址欄中,這個地址欄返回了主頁並顯示在我的瀏覽器中(我可以選擇使用任何一個主要網站/頁面分析應用程序,GA,Omniture公司Coremetrics公司等)

我使用的瀏覽器是Safari瀏覽器,所以我點擊在菜單欄中則顯示網絡督察開發。在Web Inspector的首行上,單擊Resources,找到並單擊左側列中顯示的資源列表中的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. 的谷歌Analytics(分析)參數是追加到請求URL查詢字符串 清晰可見:例如, utmsr是GA的指客戶端屏幕 分辨率變量名,對我來說,顯示值的 1280x800; utmfl是變量 名稱爲閃光版本,其具有10.3 值等

  3. 響應頭稱爲 的Content-Type(由服務器返回給客戶端發送)也確認 的資源請求並返回 是一個1x1像素的GIF: 內容類型:圖像/ GIF

這種在客戶端和服務器之間傳輸數據的一般方案已經存在了很長時間;這樣做可能是一種更好的方法,但這是我知道的唯一方法(即滿足託管分析服務強加的限制)。

+2

best回答evar – mrtsherman

+3

@doug神話般的答案,我希望我能寫出來:)可能值得提一下關於可能使用HTTP狀態代碼204作爲響應的說明,請參閱:http:// co de.google.com/speed/page-speed/docs/rtt.html我從來沒有嘗試過,但理論上它應該達到相同的目的,而不需要傳輸gif本身。 'var i = new Image(); i.src =「http://sharedcount.com/test/beacon.gif」;'是一個例子,但我不確定是否會出現任何瀏覽器問題。 – Yahel

+8

這不是最差的答案,因爲它不是答案:)我問爲什麼要提供GIF圖像,因爲所需的數據已經與請求一起發送。 – Viliam

4

這是回答OP的問題 - 「爲什麼要成爲GIF圖片資料...」

有些用戶會放一個簡單的IMG標籤打電話給你的事件日誌服務 -

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

在這種情況下,如果您沒有提供圖片,瀏覽器將顯示一個佔位符圖標,該圖標看起來很醜,給人的印象是您的服務已損壞!

我所做的是,尋找接受頭字段。當你的腳本通過IMG標籤這樣叫,你會看到這樣的請求頭下面的東西 -

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

當有「圖像/」 *字符串中的接受我提供的圖像,否則我只回覆204.

1

那麼主要原因是將cookie附加到它,所以如果用戶從一邊到另一邊,我們仍然有相同的元素來附加cookie。