为什么要提供1×1像素的GIF(networking臭虫)数据呢?

许多分析和跟踪工具正在请求1×1 GIF图像(networkingbug,用户不可见)进行跨域事件存储/处理。

为什么要提供这个GIF图像呢? 简单地返回503 Service Temporary Unavailable或者空文件这样的错误代码不是更高效吗?

更新:为了更清楚,我问为什么要提供所有必要的信息已经在请求头发送 GIF图像数据。 GIF图像本身不会返回任何有用的信息。

Doug的回答非常全面, 我想我会添加一个额外的笔记(在OP的请求,closures我的评论)

Doug的回答解释了为什么使用1×1像素信标来达到目的; 我想我会概述一个潜在的替代方法,即使用HTTP状态代码204,无内容,作为响应,而不是发送图像主体。

204无内容

服务器已经完成了请求,但不需要返回实体主体,并且可能想要返回更新后的元信息。 响应可以包含新的或更新的实体头信息,如果存在的话应该与请求的变体相关联。

基本上,服务器收到请求,并决定不发送正文(在这种情况下,不发送图像)。 但它回复了一个代码告诉代理人,这是一个有意识的决定; 基本上,它只是一个更短的方式来回应肯定。

来自Google的Page Speed文档 :

一种以asynchronous方式logging页面视图的stream行方式是在目标页面的底部包含一个JavaScript片段(或者作为一个onload事件处理器),当用户加载页面时通知日志服务器。 这样做的最常见方法是为服务器构build一个“信标”请求,并将所有感兴趣的数据作为参数编码到信标资源的URL中。 为了保持HTTP响应非常小,一个透明的1×1像素图像是一个很好的候选信标请求。 稍微更优化的信标将使用比1×1 GIF略小的HTTP 204响应(“无内容”)。

我从来没有尝试过,但从理论上讲,它应该达到相同的目的,而不需要传输gif本身,在Google Analytics(分析)的情况下可以节省35个字节。 (在这个计划中,除非你每天的Google Analytics服务有数万亿次点击,否则35个字节实际上什么都没有。)

你可以用这个代码来testing它:

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

首先,我不同意前面的两个答案 – 这个问题没有涉及。

一像素图像解决了HTTP协议中的基于networking的分析应用(如Google Analytics)的内在问题 – 如何将(networking指标)数据从客户端传输到服务器

协议所描述的最简单的方法是最简单的(至less是包含请求体的最简单的方法)是GET请求 。 根据该协议方法,客户端向服务器发起资源请求; 服务器处理这些请求并返回适当的响应。

对于像GA这样的基于networking的分析应用程序来说,这种单向scheme是个坏消息,因为它似乎并不允许服务器按需从客户端检索数据 – 所有服务器所能做的就是不提供资源请求他们。

那么从客户端获取数据回到服务器的问题有什么解决scheme? 在HTTP上下文中,除了GET之外,还有其他协议方法(例如,POST),但是由于许多原因(如其提交表单数据的频繁和专门用途所certificate的),这是有限的select。

如果您查看来自浏览器的GET请求,则会看到它包含请求URL和请求头 (例如Referer和User-Agent头),后者包含有关客户端的信息 – 例如浏览器types和版本,浏览器语言,操作系统等

再次,这是客户端发送到服务器的请求的一部分。 因此,激发一个像素gif的想法是客户端将web度量数据发送到服务器,并包装在Request Header中。

但是,那么如何让客户端请求一个资源,以便可以“欺骗”到发送度量数据? 而如何让客户端发送服务器需要的实际数据呢?

Google Analytics(分析)就是一个很好的例子: ga.js文件(下载到客户端的大文件是由网页中的一个小脚本触发的)包含几行代码, 指导客户从特定的特定资源服务器(GA服务器)并发送包装在请求标题中的某些数据。

但是由于这个请求的目的不是实际获取资源,而是向服务器发送数据,所以这个资源应该尽可能小,并且在网页中呈现时不应该是可见的 – 因此,1×1像素透明的GIF。 尺寸是可能的最小尺寸,并且格式(gif)是图像格式中最小的尺寸。

更确切地说,所有GA数据(每一个项目)都被汇编并打包到请求URL的查询string中 (“?”之后的所有内容)。 但是为了让这些数据从客户端(创build的地方)到GA服务器(在那里被logging和聚合),必须有一个HTTP请求,所以ga.js(谷歌分析脚本被下载,除非它是由客户端caching,作为页面加载时调用的函数的结果)指示客户端汇集所有分析数据 – 例如,cookie,地址栏,请求标题等 – 将其连接成单个string并将其作为查询string附加到URL( * http://www.google-analytics.com/__utm.gif* ?),并成为请求URL

使用任何浏览器来certificate这一点很容易,它允许您查看浏览器中显示的网页的HTTP请求(例如,Safari的Web Inspector ,Firefox / Chrome Firebug等)。

例如,我在浏览器的地址栏中input了一个有效的公司主页的URL,这个地址栏返回了主页并显示在我的浏览器中(我可以select任何使用主要分析应用程序的网站/页面,GA ,Omniture,Coremetrics等)

我使用的浏览器是Safari浏览器,所以我点击菜单栏中的开发 ,然后显示Web检查器 。 在Web Inspector的首行上,单击资源 ,find并单击左侧列中显示的资源列表中的utm.gif资源,然后单击Headers选项卡。 这会告诉你这样的事情:

 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/zh-CN/__utm.gif*。

  2. Google Analytics参数在附加到请求URL的查询string中清晰可见 :例如, utmsr是GA的variables名称,指的是客户端屏幕分辨率,对于我来说,显示值为1280×800; utmfl是Flash版本的variables名称,其值为10.3等

  3. Content-Type (由服务器发送回客户端)的Response Header也确认请求并返回的资源是1×1像素的gif: Content-Type:image / gif

这种在客户端和服务器之间传输数据的一般scheme已经存在了, 这样做可能是一个更好的方法,但是这是我知道的唯一方法(即满足托pipe分析服务所施加的限制)。

如果资源无法加载,某些浏览器可能会显示错误图标。 它使debugging/监控服务也变得更复杂一些,你必须确保你的监控工具把这个错误当作一个好的结果。

OTOH你什么都得不到 服务器/框架返回的错误信息通常比1×1图像大。 这意味着你增加你的networkingstream量基本上没有。

因为这样的GIF在浏览器中有一个已知的演示文稿 – 这是一个单一像素的时期。 任何其他事情都会带来视觉干扰页面实际内容的风险。

HTTP错误可能会显示为错误文本的超大帧,甚至可能是popup窗口。 一些浏览器也可能会抱怨,如果他们收到空回复。

另外,页面内的图像是默认情况下允许在所有broswers中的极less数数据types之一。 其他任何可能需要明确的用户行为才能被下载。

这是为了回答OP的问题 – “为什么要提供GIF图像数据…”

一些用户会把一个简单的img标签来调用你的事件logging服务 –

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

在这种情况下,如果您不提供图像,浏览器将显示一个占位符图标,看起来很丑,给人的印象是您的服务已经损坏!

我所做的是,查找Accept头字段。 当你的脚本通过一个像这样的img标签被调用时,你会在请求的头部看到如下的东西 –

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

Accept头域中有“image / ”*string时,我提供图像,否则我只回复204。

那么主要的原因是附加到它的cookie,所以如果用户从一边走到另一边,我们仍然有相同的元素附加cookie。