Javascript 为什么要提供 1x1 像素的 GIF(网络错误)数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6638504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why serve 1x1 pixel GIF (web bugs) data at all?
提问by Viliam
Many analytic and tracking tools are requesting 1x1 GIF image (web bug, invisible for the user) for cross-domain event storing/processing.
许多分析和跟踪工具都要求 1x1 GIF 图像(网络错误,用户不可见)用于跨域事件存储/处理。
Why to serve this GIF image at all?Wouldn't it be more efficientto simply return some error code such as 503 Service Temporary Unavailableor empty file?
为什么要提供这个 GIF 图像?简单地返回一些错误代码(例如503 Service Temporary Unavailable或空文件)不是更有效吗?
Update:To be more clear, I'm asking why to serve GIF image data when all information required has been already sentin request headers. The GIF image itself does not return any useful information.
更新:为了更清楚,我问为什么在请求标头中已经发送了所需的所有信息时为什么要提供 GIF 图像数据。GIF 图像本身不会返回任何有用的信息。
采纳答案by Yahel
Doug's answer is pretty comprehensive; I thought I'd add in an additional note (at the OP's request, off of my comment)
道格的回答非常全面;我想我会添加一个额外的注释(应 OP 的要求,在我的评论之外)
Doug's answer explains why 1x1 pixel beacons are used for the purpose they are used for; I thought I'd outline a potential alternative approach, which is to use HTTP Status Code 204, No Content, for a response, and not send an image body.
Doug 的回答解释了为什么 1x1 像素信标用于它们的用途;我想我会概述一种潜在的替代方法,即使用 HTTP 状态代码 204,无内容作为响应,而不是发送图像正文。
204 No Content
The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.
204 无内容
服务器已完成请求但不需要返回实体主体,并且可能想要返回更新的元信息。响应可以包含实体头形式的新的或更新的元信息,如果存在,应该与请求的变体相关联。
Basically, the server receives the request, and decides to not send a body (in this case, to not send an image). But it replies with a code to inform the agent that this was a conscious decision; basically, its just a shorter way to respond affirmatively.
基本上,服务器收到请求,并决定不发送正文(在这种情况下,不发送图像)。但是它会回复一个代码来通知代理这是一个有意识的决定;基本上,它只是一种更短的肯定回应方式。
From Google's Page Speed documentation:
One popular way of recording page views in an asynchronous fashion is to include a JavaScript snippet at the bottom of the target page (or as an onload event handler), that notifies a logging server when a user loads the page. The most common way of doing this is to construct a request to the server for a "beacon", and encode all the data of interest as parameters in the URL for the beacon resource. To keep the HTTP response very small, a transparent 1x1-pixel image is a good candidate for a beacon request. A slightly more optimal beacon would use an HTTP 204 response ("no content") which is marginally smaller than a 1x1 GIF.
以异步方式记录页面访问量的一种流行方式是在目标页面底部包含一个 JavaScript 片段(或作为 onload 事件处理程序),当用户加载页面时通知日志服务器。执行此操作的最常见方法是向服务器构造对“信标”的请求,并将所有感兴趣的数据编码为信标资源 URL 中的参数。为了保持 HTTP 响应非常小,透明的 1x1 像素图像是信标请求的理想候选者。稍微更优化的信标将使用比 1x1 GIF 略小的 HTTP 204 响应(“无内容”)。
I've never tried it, but in theory it should serve the same purpose without requiring the gif itself to be transmitted, saving you 35 bytes, in the case of Google Analytics. (In the scheme of things, unless you're Google Analytics serving many trillions of hits per day, 35 bytes is really nothing.)
我从未尝试过,但理论上它应该用于相同的目的,而无需传输 gif 本身,在 Google Analytics 的情况下为您节省 35 个字节。(在事情的计划中,除非您是 Google Analytics,否则每天要提供数万亿次点击,否则 35 字节真的算不了什么。)
You can test it with this code:
您可以使用以下代码对其进行测试:
var i = new Image();
i.src = "http://httpstat.us/204";
回答by doug
First, i disagree with the two previous answers--neither engages the question.
首先,我不同意前面的两个答案——都没有涉及这个问题。
The one-pixel image solves an intrinsic problem for web-based analytics apps (like Google Analytics) when working in the HTTP Protocol--how to transfer (web metrics) data from the client to the server.
单像素图像解决了基于 Web 的分析应用程序(如 Google Analytics)在 HTTP 协议中工作时的一个固有问题——如何将(Web 指标)数据从客户端传输到服务器。
The simplest of the methods described by the Protocol, the simplest (at lest the simplest method that includes a request body) is the GET request. According to this Protocol method, clients initiate requests to servers for resources; servers process those requests and return appropriate responses.
协议描述的最简单的方法,最简单的(至少是包含请求体的最简单的方法)是GET 请求。根据这种协议方式,客户端向服务器发起资源请求;服务器处理这些请求并返回适当的响应。
For a web-based analytics app, like GA, this uni-directional scheme is bad news, because it doesn't appear to allow a server to retrieve data from a client on demand--again, all servers can do is supply resources not request them.
对于基于 Web 的分析应用程序,例如 GA,这种单向方案是个坏消息,因为它似乎不允许服务器按需从客户端检索数据——同样,所有服务器能做的只是提供资源,而不是请求他们。
So what's the solution to the problem of getting data from the client back to the server?Within the HTTP context there are other Protocol methods other than GET (e.g., POST) but that's a limited option for many reasons (as evidenced by its infrequent and specialized use such as submitting form data).
那么从客户端获取数据回服务器的问题有什么解决方案呢?在 HTTP 上下文中,除了 GET(例如 POST)之外,还有其他协议方法,但由于许多原因,这是一个有限的选择(从其不经常和专门的用途,例如提交表单数据就可以证明)。
If you look at a GET Request from a browser, you'll see it is comprised of a Request URL and Request Headers(e.g., Referer and User-Agent Headers), the latter contains information about the client--e.g., browser type and version, browser langauge, operating system, etc.
如果您查看来自浏览器的 GET 请求,您会看到它由请求 URL 和请求标头(例如,Referer 和 User-Agent 标头)组成,后者包含有关客户端的信息——例如,浏览器类型和版本、浏览器语言、操作系统等。
Again, this is part of the Request that the client sends to the server. So the idea that motivates the one-pixel gif is for the client to send the web metrics data to the server, wrapped inside a Request Header.
同样,这是客户端发送到服务器的请求的一部分。因此,激发一像素 gif 的想法是让客户端将 Web 指标数据发送到服务器,并封装在请求标头中。
But then how to get the client to Request a resource so it can be "tricked" into sending the metrics data?And how to get the client to send the actual data the server wants?
但是如何让客户端请求资源,以便它可以被“欺骗”发送指标数据?以及如何让客户端发送服务器想要的实际数据?
Google Analytics is a good example: the ga.jsfile (the large file whose download to the client is triggered by a small script in the web page) includes a few lines of code that directs the client to request a particular resource from a particular server (the GA server) and to send certain data wrapped in the Request Header.
Google Analytics 就是一个很好的例子:ga.js文件(由网页中的一个小脚本触发下载到客户端的大文件)包含几行代码,用于指示客户端从特定服务器(GA 服务器)并发送包含在请求头中的某些数据。
But since the purpose of this Request is not to actually get a resource but to send data to the server, this resource should be a small as possible and it should not be visible when rendered in the web page--hence, the 1 x 1 pixel transparent gif. The size is the smallest size possible, and the format (gif) is the smallest among the image formats.
但是由于这个 Request 的目的不是实际获取资源,而是向服务器发送数据,所以这个资源应该尽可能小,并且在网页中呈现时它不应该是可见的——因此,1 x 1像素透明gif。尺寸是可能的最小尺寸,格式(gif)是图像格式中最小的。
More precisely, all GA data--every single item--is assembled and packed into the Request URL's query string(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 Request URL.
更准确地说,所有 GA 数据——每一个项目——都被组装并打包到请求 URL 的查询字符串中('?' 之后的所有内容)。但是为了让数据从客户端(创建它的地方)到 GA 服务器(记录和聚合它的地方)必须有一个 HTTP 请求,所以 ga.js(下载的谷歌分析脚本,除非它是由客户端缓存,作为页面加载时调用的函数的结果)指示客户端组合所有分析数据 - 例如,cookie、位置栏、请求标头等 - 将其连接成单个字符串并将其作为查询字符串附加到 URL ( *http://www.google-analytics.com/__utm.gif*?) 后成为请求 URL。
It's easy to prove this using any web browser that has allows you to view the HTTP Request for the web page displayed in your browser (e.g., Safari's Web Inspector, Firefox/Chrome Firebug, etc.).
使用任何允许您查看浏览器中显示的网页的 HTTP 请求的 Web 浏览器(例如,Safari 的Web Inspector、Firefox/Chrome Firebug等)都可以轻松证明这一点。
For instance, i typed in valid url to a corporate home page into my browser's location bar, which returned that home page and displayed it in my browser (i could have chosen any web site/page that uses one of the major analytics apps, GA, Omniture, Coremetrics, etc.)
例如,我在浏览器的位置栏中输入了公司主页的有效 url,它返回该主页并将其显示在我的浏览器中(我可以选择使用主要分析应用程序之一的任何网站/页面,GA 、Omniture、Coremetrics 等)
The browser i used was Safari, so i clicked Developin the menu bar then Show Web Inspector. On the top row of the Web Inspector, click Resources, find and click the utm.gif resource from the list of resources shown on the left-hand column, then click the Headerstab. That will show you something like this:
我使用的浏览器是 Safari,所以我点击菜单栏中的Develop,然后点击Show Web Inspector。在 Web Inspector 的顶行,单击Resources,从左列显示的资源列表中找到并单击 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
The key points to notice are:
需要注意的关键点是:
The Request was in fact a request for the utm.gif, as evidenced by the first line above: *Request URL:http://www.google-analytics.com/__utm.gif*.
The Google Analytics parameters are clearly visible in the query string appended to the Request URL: e.g., utmsris GA's variable name to refer to the client screen resolution, for me, shows a value of 1280x800; utmflis the variable name for flash version, which has a value of 10.3, etc.
The Response Headercalled Content-Type(sent by the server back to the client) also confirms that the resource requested and returned was a 1x1 pixel gif: Content-Type:image/gif
该请求实际上是对 utm.gif 的请求,如上面第一行所示:*请求 URL:http://www.google-analytics.com/__utm.gif*。
Google Analytics 参数在附加到请求 URL 的查询字符串中清晰可见:例如, utmsr是 GA 的变量名称,用于指代客户端屏幕分辨率,对我而言,显示值为 1280x800;utmfl是 flash 版本的变量名,值为 10.3 等。
名为 Content-Type的响应头(由服务器发送回客户端)也确认请求和返回的资源是 1x1 像素的 gif: Content-Type:image/gif
This general scheme for transferring data between a client and a server has been around forever; there could very well be a better way of doing this, but it's the only way i know of (that satisfies the constraints imposed by a hosted analytics service).
这种在客户端和服务器之间传输数据的通用方案一直存在。很可能有更好的方法来做到这一点,但这是我所知道的唯一方法(满足托管分析服务施加的约束)。
回答by Ulrich Dangel
Some browsers may display an error icon if the resource could not load. It makes debugging/monitoring the service also a little bit more complicated, you have to make sure that your monitoring tools treat the error as a good result.
如果资源无法加载,某些浏览器可能会显示错误图标。它使调试/监控服务也变得更加复杂,您必须确保您的监控工具将错误视为一个好的结果。
OTOH you don't gain anything. The error message returned by the server/framework is typically bigger then the 1x1 image. This means you increase your network traffic for basically nothing.
OTOH你什么也得不到。服务器/框架返回的错误消息通常比 1x1 图像大。这意味着您基本上无需增加网络流量。
回答by thkala
Because such a GIF has a known presentation in a browser - it's a single pixel, period. Anything else presents a risk of visually interfering with the actual content of the page.
因为这样的 GIF 在浏览器中有一个已知的展示 - 它是一个像素,周期。其他任何内容都有在视觉上干扰页面实际内容的风险。
HTTP errors could appear as oversized frames of error text or even as a pop-up window. Some browsers may also complain if they receive empty replies.
HTTP 错误可能显示为过大的错误文本帧,甚至显示为弹出窗口。如果收到空回复,某些浏览器也可能会抱怨。
In addition, in-page images are one of the very few data types allowed by default in all broswers. Anything else may require explicit user action to be downloaded.
此外,页内图像是所有浏览器中默认允许的极少数数据类型之一。其他任何内容都可能需要下载明确的用户操作。
回答by Harmeet
This is to answer the OP's question - "why to serve GIF image data..."
这是为了回答 OP 的问题——“为什么要提供 GIF 图像数据......”
Some users will put a simple imgtag to call your event logging service -
一些用户会放一个简单的img标签来调用你的事件日志服务——
<img src="http://www.example.com/logger?event_id=1234">
In this case, if you don't serve an image, the browser will show a placeholder icon that will look ugly and give the impression that your service is broken!
在这种情况下,如果您不提供图像,浏览器将显示一个占位符图标,该图标看起来很丑陋,给人的印象是您的服务已损坏!
What I do is, look for the Acceptheader field. When your script is called via an imgtag like this, you will see something like following in the header of the request -
我所做的是,查找Accept标头字段。当您的脚本通过这样的img标签被调用时,您将在请求的标头中看到如下内容 -
Accept: image/gif, image/*
Accept-Encoding:gzip,deflate
...
When there is "image/"* string in the Acceptheader field, I supply the image, otherwise I just reply with 204.
当Accept头字段中有"image/"* 字符串时,我提供图像,否则我只回复 204。
回答by Maciej Perliński
Well the major reason is to attach the cookie to it so if users go from one side to another we still have the same element to attach cookie to.
嗯,主要原因是将 cookie 附加到它,因此如果用户从一侧转到另一侧,我们仍然可以将 cookie 附加到相同的元素。
回答by fauverism
You don't have to serve an image if you are using the Beacon API (https://w3c.github.io/beacon/) implementation method.
如果您使用 Beacon API ( https://w3c.github.io/beacon/) 实现方法,则不必提供图像。
An error code would work if you have access to the log files of your server. The purpose of serving the image is to obtain more data about the user than you normally would with a log file.
如果您有权访问服务器的日志文件,则错误代码将起作用。提供图像的目的是获得比通常使用日志文件更多的关于用户的数据。
回答by Elad Yosifon
@Maciej Perliński is basically correct, but I feel a detailed answer will be beneficial.
@Maciej Perliński 基本上是正确的,但我觉得详细的答案会有所帮助。
why 1x1 GIF and not a 204 No-Content
status code?
为什么是 1x1 GIF 而不是204 No-Content
状态码?
204 No-Content
enables the server to omit all response headers (Content-Type, Content-Length, Content-Encoding, Cache-Control etc...) and return an empty response body with 0 bytes (and saving a lot of unneeded bandwidth).
204 No-Content
使服务器能够省略所有响应头(内容类型、内容长度、内容编码、缓存控制等)并返回一个 0 字节的空响应主体(并节省大量不需要的带宽)。
Browsers know to respect 204 No-Content
responses, and not to expect/wait for response headers and response body.
浏览器知道尊重204 No-Content
响应,而不是期待/等待响应标头和响应正文。
if the server needs to set any response header (e.g. cache-control
or cookie
), he cannot use 204 No-Content
because browsers will ignore any response header by design (according to the HTTP protocol spec).
如果服务器需要设置任何响应头(例如cache-control
或cookie
),他不能使用,204 No-Content
因为浏览器会故意忽略任何响应头(根据 HTTP 协议规范)。
why 1x1 GIF and not a Content-Length: 0
header with 200 OK
status code?
为什么是 1x1 GIF 而不是Content-Length: 0
带有200 OK
状态代码的标题?
Probably a mix of several issues, just to name a few:
可能是几个问题的混合,仅举几例:
- legacy browsers compatibility
- MIME type checks on browsers, 0 bytes is not a valid image.
200 OK
with 0 bytes might not be fully supported by intermediate proxy servers and VPNs
- 旧浏览器兼容性
- 浏览器上的 MIME 类型检查,0 字节不是有效图像。
200 OK
中间代理服务器和 VPN 可能不完全支持 0 字节