许多分析和追踪工具要求请求一个1x1像素的GIF图像(网络虫,用户不可见)用于跨域事件存储/处理。
为什么需要提供这个GIF图像呢? 直接返回一些错误代码比如503 Service Temporary Unavailable或者空文件不是更高效吗?
更新:更明确地说,我想问的是为什么在请求标头中已经传输了所有所需信息时还需要提供GIF图像数据。 GIF图像本身并没有返回任何有用的信息。
许多分析和追踪工具要求请求一个1x1像素的GIF图像(网络虫,用户不可见)用于跨域事件存储/处理。
为什么需要提供这个GIF图像呢? 直接返回一些错误代码比如503 Service Temporary Unavailable或者空文件不是更高效吗?
更新:更明确地说,我想问的是为什么在请求标头中已经传输了所有所需信息时还需要提供GIF图像数据。 GIF图像本身并没有返回任何有用的信息。
基本上,服务器接收到请求后,决定不发送正文(在这种情况下,不发送图像)。但是,它会回复一个代码来通知代理这是一个有意识的决定;基本上,这只是一种更短的肯定回复方式。204 No Content
服务器已经满足请求,但不需要返回实体正文,并且可能希望返回更新的元信息。响应可以包括新的或更新的实体头信息,如果存在,则应与请求的变体相关联。
var i = new Image();
i.src = "http://httpstat.us/204";
首先,我不同意前面两个回答--它们都没有涉及到问题。
一像素图片解决了基于Web的分析应用程序(如Google Analytics)在使用HTTP协议时的内在问题--如何将(Web指标)数据从客户端传输到服务器。
协议描述的最简单方法之一是GET请求,它是包含请求正文的最简单的方法(至少是包含请求正文的最简单方法)。根据此协议方法,客户端启动请求以获取资源;服务器处理这些请求并返回适当的响应。
对于像GA这样的基于Web的分析应用程序,这种单向方案是个坏消息,因为它似乎不允许服务器按需从客户端检索数据--再次强调,所有服务器能做的就是提供资源而不是请求他们。
那么如何解决将数据从客户端传回服务器的问题呢? 在HTTP上下文中,除了GET(例如POST)之外还有其他协议方法,但出于许多原因,这是一个有限的选项(如提交表单数据时的专用使用频率较低)。
如果你查看浏览器发出的GET请求,你会发现它由一个请求URL和请求头(如Referer和User-Agent头)组成,后者包含有关客户端的信息--如浏览器类型和版本、浏览器语言、操作系统等。
同样,这是客户端发送给服务器的请求的一部分。因此,驱动一个像素gif的想法是让客户端将Web度量标准数据封装在一个请求头中发送到服务器。
但是,如何让客户端请求资源,以便可以“欺骗”它发送指标数据?以及如何让客户端发送服务器想要的实际数据?
谷歌分析是一个很好的例子:其中的ga.js文件(由网页中的小脚本触发并向客户端下载)包括几行代码,指导客户端从特定服务器(GA服务器)请求特定资源,并在请求头中传递一些数据。
但由于此请求的目的不是获取资源,而是向服务器发送数据,因此该资源应尽可能小,并且在网页中呈现时不应可见——因此,使用了1 x 1像素的透明gif。该大小是可能的最小值,而且格式(gif)是各种图像格式中最小的。
更精确地说,所有GA数据——每个项目——都被组装并打包到请求URL的查询字符串中('?'之后的内容)。但为了使这些数据从客户端(创建位置)传输到GA服务器(记录和聚合位置),必须进行HTTP请求,因此ga.js(可以通过页面加载时调用的函数来下载的谷歌分析脚本,除非它已被缓存)指导客户端将所有分析数据(例如cookie、地址栏、请求头等)连接成一个字符串,并将其附加为查询字符串添加到URL(*http://www.google-analytics.com/__utm.gif*?),并成为请求URL。
可以使用任何允许您查看浏览器中显示的Web页面的HTTP请求的Web浏览器来证明这一点(例如,Safari的Web Inspector、Firefox/Chrome的Firebug等)。
例如,我在我的浏览器地址栏中输入有效URL到公司主页,返回了该主页并在我的浏览器中显示它(我可以选择使用使用GA、Omniture、Coremetrics等主要分析应用程序之一的任何网站/页面)。
我使用的浏览器是Safari,所以我在菜单栏中点击了开发,然后选择显示Web检查器。在Web检查器的顶部行中,点击资源,从左侧列出的资源列表中找到并点击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
需要注意的关键点有:
请求实际上是请求utm.gif文件,这可以从上面的第一行看出来:Request URL:http://www.google-analytics.com/__utm.gif
谷歌分析参数在Query字符串中清晰可见,例如utmsr是GA的变量名,用于表示客户端屏幕分辨率,对我而言,它显示的是1280x800;utmfl是Flash版本的变量名,其值为10.3等。
响应头称为Content-Type(服务器发送给客户端),也确认了所请求和返回的资源是1x1像素的gif图像:Content-Type:image/gif
HTTP状态码204
作为响应的注释。参见此处:http://code.google.com/speed/page-speed/docs/rtt.html。虽然我从未尝试过,但从理论上讲,它应该可以在不需要传输gif本身的情况下实现相同的目的。`var i=new Image(); i.src = "http://sharedcount.com/test/beacon.gif";` 是一个示例,但我不确定它是否会有任何浏览器问题。 - Yahel一些浏览器可能会显示错误图标,如果资源无法加载。这使得调试/监控服务变得更加复杂,您必须确保您的监控工具将错误视为良好结果。
另一方面,您不会获得任何东西。服务器/框架返回的错误消息通常比1x1图像大。这意味着您增加了网络流量,但几乎没有获得任何实际效益。
<noscript>
中即可正常工作。而且,您无需在服务器端进行任何操作来区分通过js请求的请求(返回错误)和直接通过DOM元素请求(返回图像)。 - Ulrich Dangel<img src="http://www.example.com/logger?event_id=1234">
Accept: image/gif, image/*
Accept-Encoding:gzip,deflate
...
如果接收头字段中包含"image/"*字符串,我提供图像,否则只回复204状态码。
主要原因是将cookie附加到其中,这样如果用户从一侧转到另一侧,我们仍然有相同的元素来附加cookie。
如果你使用的是Beacon API (https://w3c.github.io/beacon/)实现方法,那么就不必提供图片。
如果你可以访问服务器的日志文件,那么错误代码也能起作用。提供图片的目的在于获得比普通日志文件更多的用户数据。