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

许多分析和跟踪工具请求1x1的 GIF 图像(web bug,用户看不见)用于跨域事件存储/处理。

为什么要提供这个 GIF 图片呢?返回一些错误代码(如 503服务暂时无法使用或空文件)不就是 更有效率了吗?

更新: 为了更清楚,我问为什么要服务的 GIF 图像数据时,所有的信息需要 已经发出去了在请求头。GIF 图像本身不返回任何有用的信息。

39692 次浏览

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

你什么也得不到。服务器/框架返回的错误消息通常比1x1映像大。这意味着你增加你的网络流量基本上没有任何意义。

因为这样的 GIF 在浏览器中有一个已知的表示——它是一个单一的像素,句号。其他任何东西都有可能在视觉上干扰页面的实际内容。

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

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

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

单像素图像解决了基于 Web 的分析应用程序(如 Google Analytics)在使用 HTTP 协议 如何将(web 指标)数据从客户端传输到服务器时的一个内在问题。

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

对于像 GA 这样的基于网络的分析应用程序来说,这种单向模式是个坏消息,因为它似乎不允许服务器根据需要从客户端检索数据——同样,服务器所能做的只是提供资源而不是请求它们。

那么,如何解决将数据从客户机返回到服务器的问题呢?在 HTTP 上下文中,除了 GET 还有其他的 Protocol 方法(例如,POST) ,但是由于很多原因,这是一个有限的选择(例如,它很少使用并且专门用于提交表单数据)。

如果你从浏览器中查看 GET 请求,你会发现它由请求 URL 和 请求标题(例如,引用者和用户代理头)组成,后者包含客户端的信息——例如,浏览器类型和版本,浏览器语言,操作系统等等。

同样,这是客户机发送给服务器的请求的一部分

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

Google Analytics 就是一个很好的例子: Ga.js文件(由网页中的一个小脚本触发下载到客户端的大型文件)包含几行代码

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

More precisely, all GA data--every single item--is assembled and packed into the < em > 请求 URL 的查询字符串 (everything after the '?'). But in order for that data to go from the client (where it is created) to the GA server (where it is logged and aggregated) there must be an HTTP Request, so the ga.js (google analytics script that's downloaded, unless it's cached, by the client, as a result of a function called when the page loads) directs the client to assemble all of the analytics data--e.g., cookies, location bar, request headers, etc.--concatenate it into a single string and append it as a query string to a URL (* http://www.google-analytics.com/__utm.gif* ?) and that becomes the 请求 URL.

很容易证明这一点,使用任何网络浏览器,让您查看网页的 HTTP 请求显示在您的浏览器(例如,Safari 的 网络监察员,Firefox/Chrome 的 纵火犯等)。

例如,我在浏览器的位置栏中输入了一个企业主页的有效网址,它会返回该主页并显示在我的浏览器中(我本可以选择任何使用主要分析应用程序之一的网站/页面,例如 GA、 Omfamily、 Coremetrics 等)

我使用的浏览器是 Safari,所以我点击菜单栏中的 冲洗,然后是 给网络检查员看看。在 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,如 上面第一行: * 请求 网址: http://www.google-analytics.com/__utm.gif*

  2. GoogleAnalytics 参数在查询字符串中清晰可见 附加到请求 URL : 例如, Utmsr 是 GA 引用客户机屏幕的变量名 对我来说,分辨率显示了 Utmfl是变量 Flash 版本的名称,该版本具有 值为10.3等

  3. 响应主管来电话了 Content-Type (由服务器发送回客户端)也确认 请求的资源和 返回的是一个1x1像素的 gif: 内容-类型: image/gif

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

Doug 的回答相当全面; 我想我应该添加一个附加说明(应 OP 的要求,从我的评论中删除)

道格的回答解释了为什么1x1像素的信标被用于他们的目的,我想我会概述一个潜在的替代方法,那就是使用 HTTP状态码204,无内容,作为一个响应,而不是发送一个图像主体。

204无内容

服务器已经完成了请求 但不需要返回 并且可能希望返回 更新的元信息,响应 可能包括新的或更新的 以... 的形式存在的 实体标头,如果存在 应该与 请求的变体。

基本上,服务器接收请求,并决定不发送主体(在这种情况下,不发送图像)。但是它会用一个代码来告诉代理,这是一个有意识的决定; 基本上,这只是一个简短的方式来做出肯定的回应。

来自 Google 的 Page Speed 文档:

一种流行的记录页面的方法 以异步方式显示的视图是 中包含一个 JavaScript 代码片段 目标页的底部(或作为 Onload 事件处理程序) ,它通知一个 当用户加载 最常用的方法 这是为了构造对 服务器的“信标”,并编码所有 感兴趣的数据作为参数 信标资源的 URL 保持 HTTP 响应非常小 透明的1x1像素的图像是一个很好的 信标请求的候选人 更理想的信标 HTTP204响应(“无内容”) 比1x1小一点 GIF.

我从来没有尝试过,但理论上它应该服务于同样的目的,而不需要传输 gif 本身,节省你35字节,在谷歌分析的情况下。(从整体上看,除非你是谷歌分析(Google Analytics) ,每天提供数万亿次点击,否则35字节真的不算什么。)

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

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

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

有些用户会放一个简单的 IMG标签来调用您的事件日志服务-

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

在这种情况下,如果您没有提供图像,浏览器将显示一个占位符图标,这个图标看起来很丑陋,给人的印象是您的服务中断了!

我要做的是,查找 接受头字段。当通过类似这样的 IMG标记调用脚本时,您将在请求-的头部看到类似如下的内容

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

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

主要原因是要将 cookie 附加到它上面,这样如果用户从一边到另一边,我们仍然可以将 cookie 附加到相同的元素上。

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

如果可以访问服务器的日志文件,则错误代码将起作用。提供映像的目的是获得关于用户的更多数据,而不是使用日志文件。

@ Maciej Perli 斯基基本上是正确的,但我觉得一个详细的答案将是有益的。

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

204 No-Content允许服务器省略所有响应头(内容类型、内容长度、内容编码、缓存控制等)。.)并返回一个0字节的空响应主体(并且节省了大量不需要的带宽)。

浏览器知道要尊重 204 No-Content响应,不要期望/等待响应头和响应主体。

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

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

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

  • 遗留浏览器兼容性
  • 在浏览器上检查 MIME 类型,0字节不是有效的图像。
  • 中间代理服务器和 VPN 可能不完全支持字节为0的 200 OK