为什么要完全提供1x1像素的GIF(网络错误)数据?


81

许多分析和跟踪工具都要求1x1 GIF图像(网络错误,对于用户不可见)以进行跨域事件存储/处理。

为什么要完全投放此GIF图片?简单地返回一些错误代码(例如503 Service Temporary Unavailable或空文件)会更有效吗?

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

Answers:


70

道格的答案很全面。我以为我会补充一条便条(应OP的要求,我的评论不对)

道格的答案解释了为什么将1x1像素信标用于其用途。我以为我概述了一种潜在的替代方法,该方法是使用HTTP状态代码204(无内容)作为响应,而不发送图像主体。

204没有内容

服务器已满足请求,但不需要返回实体,可能要返回更新的元信息。响应可以以实体标题的形式包含新的或更新的元信息,如果存在,则应与所请求的变量相关联。

基本上,服务器接收请求,并决定不发送正文(在这种情况下,不发送图像)。但是它会回复代码以通知代理,这是一个有意识的决定。基本上,这只是肯定回答的一种较短方法。

Google的Page Speed文档中

一种以异步方式记录页面视图的流行方法是在目标页面底部(或作为onload事件处理程序)包括一个JavaScript代码段,当用户加载页面时,该代码段会通知日志记录服务器。最常见的方法是为服务器建立“信标”请求,并将所有感兴趣的数据编码为信标资源的URL中的参数。为使HTTP响应保持很小,透明的1x1像素图像是信标请求的理想选择。稍微更好的信标将使用HTTP 204响应(“无内容”),该响应略小于1x1 GIF。

我从未尝试过,但是从理论上讲,它应该达到相同的目的,而不需要传输gif本身,对于Google Analytics(分析)来说,可以节省35个字节。(按照情况来看,除非您每天使用Google Analytics(分析)提供数以万亿计的点击量,否则35个字节实际上是没有用的。)

您可以使用以下代码对其进行测试:

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

12
这些鲜为人知的HTTP状态代码(203、204、205)确实是金。他们应该看到比目前更多的使用。

1
不错-实际上我可以使用的信息。向我+1。
doug

1
让我看看是否可以总结一下-HTTP响应代码方法涉及相同的客户端请求;唯一的区别是服务器而不是返回1x1 gif(我想应该是200),而是将204返回给客户端?
doug

2
您如何请求返回204响应代码的东西?
尔根·保罗

3
我不明白为什么要图片。为什么不返回空字符串?
曾伟诗

65

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

一像素图像解决了使用HTTP协议工作时基于Web的分析应用程序(例如Google Analytics(分析))的一个固有问题,即如何从客户端向服务器传输(Web指标)数据

协议描述的最简单的方法,最简单的(至少是包括请求正文的最简单的方法)是GET request。根据此协议方法,客户端向服务器发起资源请求。服务器处理这些请求并返回适当的响应。

对于基于GA的基于网络的分析应用程序来说,这种单向方案是个坏消息,因为它似乎不允许服务器按需从客户端检索数据-同样,所有服务器可以做的就是提供资源而不是请求他们。

那么,如何将数据从客户端传回服务器的解决方案是什么?在HTTP上下文中,除了GET(例如POST)以外,还有其他协议方法,但是由于许多原因,这是一个有限的选择(如其不经常使用和专门使用(例如提交表单数据所证明))。

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

同样,这是客户端发送到服务器的请求的一部分。因此,激发一像素gif的想法是让客户端将Web度量数据发送到服务器,并包装在请求标头中。

但是,然后如何使客户端请求资源以使其“诱骗”发送度量数据呢?以及如何使客户端发送服务器所需的实际数据?

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

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

更准确地说,所有GA数据(每个项目)都被组合并打包到请求URL的查询字符串中(“?”之后的所有内容)。但是,为了使该数据从客户端(在其中创建数据)到GA服务器(在其中进行记录和汇总),必须有一个HTTP请求,因此ga.js(已下载的Google Analytics(分析)脚本,除非已由于页面加载时调用的函数而被客户端缓存),指示客户端将所有分析数据(例如Cookie,位置栏,请求标头等)组合在一起,将其合并为一个字符串并将其作为查询字符串附加到URL(* http://www.google-analytics.com/__utm.gif*?)上,并成为请求URL

使用任何允许您查看浏览器中显示的网页的HTTP请求的网络浏览器(例如Safari的Web Inspector,Firefox / Chrome Firebug等),即可轻松证明这一点。

例如,我在浏览器的位置栏中输入了指向公司主页的有效URL,该URL返回了该主页并将其显示在浏览器中(我可以选择使用主要分析应用之一GA的任何网站/页面,Omniture,Coremetrics等)

我使用的浏览器是Safari,因此在菜单栏中单击Develop,然后单击Show Web Inspector。在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

需要注意的关键点是:

  1. 如上第一行所示,该请求实际上是对utm.gif的请求:*请求URL:http://www.google-analytics.com/__utm.gif*。

  2. Google Analytics(分析)参数在添加到请求URL的查询字符串中清晰可见:例如, utmsr是GA的变量名称,用于引用客户端屏幕分辨率,对我来说显示为1280x800;utmfl是Flash版本的变量名,其值为10.3,依此类推

  3. 称为 Content-Type响应标头(由服务器发送回客户端)还确认请求并返回的资源为1x1像素gif: Content-Type:image / gif

这种在客户端和服务器之间传输数据的通用方案已经存在了很长时间。可能会有更好的方法,但这是我所知道的唯一方法(它满足了托管分析服务所施加的约束)。


3
@doug很棒的答案。我希望我写了它:)可能值得一提关于可能被HTTP Status Code 204用于响应的注释。参见:code.google.com/speed/page-speed/docs/rtt.html我从未尝试过,但是从理论上讲,它应该达到相同的目的,而不需要传输gif本身。var i=new Image(); i.src = "http://sharedcount.com/test/beacon.gif";是一个示例,但我不确定是否会出现任何浏览器问题。
Yahel 2011年

9
这不是最糟糕的答案,因为它不是答案。)我问为什么要完全提供GIF图像,因为所需的数据已经随请求一起发送了。
维利亚姆

2
我不想太消极,对不起。这是对网络错误的很好的解释。但是为什么要回送GIF数据呢?
维利亚姆

@yahelc:太好了。考虑将其添加为其他人的答案。作为评论,它几乎是看不见的。
维利亚姆

@Villiam当然可以,只需添加即可。
Yahel 2011年

14

如果无法加载资源,某些浏览器可能会显示错误图标。这会使调试/监视服务也变得更加复杂,您必须确保监视工具将错误视为一个好结果。

太太,你什么也得不到。服务器/框架返回的错误消息通常大于1x1图像。这意味着您基本上不需要增加网络流量。


1
分析应用程序(例如Google Analytics,Yahoo Analytics,Omniture等)在网页上放置1x1像素gif图像的原因与“调试”应用程序完全无关
doug

3
@doug-我认为mru的意思是,如果您故意返回错误代码,则必须区分“ true”错误代码和要返回的错误代码。因此,故事的寓意是,当结果是预期的结果时,切勿返回错误代码。
Moo

3
我怀疑错误响应会比GIF图像大-请注意,与GIF图像一起发送的响应为200 OK。
维利亚姆

2
@Villiam大多数环境不仅返回错误代码,而且返回描述错误/提供更多信息的漂亮HTML页面。
Ulrich Dangel,2011年

8

因为这样的GIF在浏览器中具有已知的表示形式-它是一个像素周期。其他任何情况都可能在视觉上干扰页面的实际内容。

HTTP错误可能显示为错误文本的超大框架,甚至显示为弹出窗口。如果某些浏览器收到空的答复,他们可能也会抱怨。

此外,页内图像是所有浏览器中默认允许的极少数数据类型之一。其他任何内容都可能需要明确的用户操作才能下载。


1
您的回答没有说​​明服务资源的目的-即为什么根本需要服务资源?您的答案针对的问题是:“为什么要提供1x1 gif而不是另一种图像格式?这是一个琐碎的问题,并且有一个琐碎的答案(即gif格式在逐像素的基础上比jpeg,png的大小更小) ,tiff等)
doug

您可以使用Javascript Image对象调用GIF加载。它不会向用户报告任何错误。
维利亚姆

@Villiam通过真正返回图像,您还可以在未启用javascript的情况下跟踪浏览器,只需将image标记放入即可<noscript>,它将起作用。而且,您无需在服务器端执行任何操作即可区分通过js请求(返回错误)和直接通过DOM中的元素进行请求(返回图像)之间的
区别

4

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

一些用户将放置一个简单的img标签来调用您的事件记录服务-

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

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

我要做的是,寻找“接受”标头字段。当通过这样的img标签调用脚本时,您会在请求的标头中看到类似以下内容的内容-

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

接受”标头字段中有“ image / ” *字符串时,我提供图像,否则我只返回204。


2

好吧,主要原因是要在其上附加cookie,因此,如果用户从一侧移到另一侧,我们仍然具有相同的元素来附加cookie。


0

如果使用Beacon API(https://w3c.github.io/beacon/)实现方法,则无需提供图像。

如果您有权访问服务器的日志文件,则错误代码将起作用。提供图像的目的是获得与用户通常使用日志文件相比更多的有关用户的数据。


0

@MaciejPerliński基本上是正确的,但我认为详细的回答将是有益的。

为什么使用1x1 GIF而不是204 No-Content状态码?

204 No-Content 使服务器可以忽略所有响应标头(内容类型,内容长度,内容编码,缓存控制等),并返回一个空字节的响应正文,该字节为0字节(并节省了大量不必要的带宽)。

浏览器知道尊重204 No-Content响应,而不期望/等待响应标头和响应正文。

如果服务器需要设置任何响应标头(例如cache-controlcookie),则他不能使用,204 No-Content因为浏览器将根据设计忽略任何响应标头(根据HTTP协议规范)。

为什么是1x1 GIF,而不是Content-Length: 0带有200 OK状态码的标头?

可能是几个问题的混合,仅举几例:

  • 旧版浏览器的兼容性
  • 浏览器上的MIME类型检查,0字节不是有效的图像。
  • 200 OK 中间代理服务器和VPN可能不完全支持0字节的数据
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.