Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 49 题:为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片? #87

Open
zeroone001 opened this issue Apr 7, 2019 · 22 comments

Comments

@zeroone001
Copy link

作用:工作中,用于前端监控,比如曝光等等,谷歌和百度的都是用的1x1 像素的透明 gif 图片;
why?

  1. 没有跨域问题,一般这种上报数据,代码要写通用的;(排除ajax)
  2. 不会阻塞页面加载,影响用户的体验,只要new Image对象就好了;(排除JS/CSS文件资源方式上报)
  3. 在所有图片中,体积最小;(比较PNG/JPG)
@noctiomg
Copy link

noctiomg commented Apr 8, 2019

补充楼上~以下为参考了网上资料后的一些个人整理:

  1. 能够完成整个 HTTP 请求+响应(尽管不需要响应内容)
  2. 触发 GET 请求之后不需要获取和处理数据、服务器也不需要发送数据
  3. 跨域友好
  4. 执行过程无阻塞
  5. 相比 XMLHttpRequest 对象发送 GET 请求,性能上更好
  6. GIF的最低合法体积最小(最小的BMP文件需要74个字节,PNG需要67个字节,而合法的GIF,只需要43个字节)

参考资料:
SegmentFault 上的回答
Web beacon
Using a Beacon Image for GitHub, Website and Email Analytics
为什么前端监控要用 GIF 打点

@lvtraveler
Copy link

  1. 避免跨域(img 天然支持跨域)
  2. 利用空白gif或1x1 px的img是互联网广告或网站监测方面常用的手段,简单、安全、相比PNG/JPG体积小,1px 透明图,对网页内容的影响几乎没有影响,这种请求用在很多地方,比如浏览、点击、热点、心跳、ID颁发等等,
  3. 图片请求不占用 Ajax 请求限额
  4. 不会阻塞页面加载,影响用户的体验,只要new Image对象就好了,一般情况下也不需要append到DOM中,通过它的onerror和onload事件来检测发送状态。
    示例:
<script type="text/javascript">
 var thisPage = location.href;
 var referringPage = (document.referrer) ? document.referrer : "none";
 var beacon = new Image();
 beacon.src = "http://www.example.com/logger/beacon.gif?page=" + encodeURI(thisPage)
 + "&ref=" + encodeURI(referringPage);
</script>


@swchenxixi
Copy link

英文术语叫:image beacon
在Google 的 Make the Web Faster 的 #Track web traffic in the background 中有提到。

主要应用于只需要向服务器发送数据(日志数据)的场合,且无需服务器有消息体回应。比如收集访问者的统计信息。

一般做法是服务器用一个1x1的gif图片来作为响应,当然这有点浪费服务器资源。因此用header来响应比较合适,目前比较合适的做法是服务器发送"204 No Content",即“服务器成功处理了请求,但不需要返回任何实体内容”。

另外该脚本的位置一般放在页面最后以免阻塞页面渲染,并且一般情况下也不需要append到DOM中。通过它的onerror和onload事件来检测发送状态。

<script type="text/javascript">
 var thisPage = location.href;
 var referringPage = (document.referrer) ? document.referrer : "none";
 var beacon = new Image();
 beacon.src = "http://www.example.com/logger/beacon.gif?page=" + encodeURI(thisPage)
 + "&ref=" + encodeURI(referringPage);
</script>

这样做和ajax请求的区别在于:
1.只能是get请求,因此可发送的数据量有限。
2.只关心数据是否发送到服务器,服务器不需要做出消息体响应。并且一般客户端也不需要做出响应。
3.实现了跨域。

@formattedzzz
Copy link

好问题,连题干都没抓住😂

@swchenxixi
Copy link

好问题,连题干都没抓住

我…….jpg (,,Ծ‸Ծ,,)

@zhongmeizhi
Copy link

楼上的大佬们,你们的答案和 <script async src="埋点"></script> 有什么区别?这样埋点还能各式各样了。

@yiqingfeng
Copy link

楼上的大佬们,你们的答案和 <script async src="埋点"></script> 有什么区别?这样埋点还能各式各样了。

图片资源相对于 script 这种文件请求方式而言,不需要额外注入DOM,性能更好。只需要在js中 new Image 就能发起请求,同时造成阻塞。

@LiuMengzhou
Copy link

楼上的大佬们,你们的答案和 <script async src="埋点"></script> 有什么区别?这样埋点还能各式各样了。

图片资源相对于 script 这种文件请求方式而言,不需要额外注入DOM,性能更好。只需要在js中 new Image 就能发起请求,同时造成阻塞。

同时 不 造成阻塞。

@xiaocode337317439
Copy link

nginx默认内置ngx_http_empty_gif_module模块, 而且nginx里面的空白图片是保存在内存中的,速度绝对比硬盘上读取的快。

@GzhiYi
Copy link

GzhiYi commented Jul 13, 2019

写过第三方嵌入脚本,比如说统计代码之类的就比较清楚。beacon不止new一个image,作用是图片请求,无跨域问题,无阻塞。使用的时候注意图片会有缓存。

@ragnar-document
Copy link

这和jsonp差不多吧

@wind4gis
Copy link

可以用new image发起一个请求,后台服务器直接返回204响应码,这样子连图片都省了。。。

@rick-you
Copy link

补充点:使用image时,部分浏览器内页面关闭不会影响数据上报

@ace0109
Copy link

ace0109 commented Oct 15, 2019

想问一下,后端是怎么处理这样的链接请求过来的。后端提供的接口就是叫xxx.gif?还是这就是一张图片的请求,那后端怎么拦截?

@D-lyw
Copy link

D-lyw commented Oct 15, 2019

想问一下,后端是怎么处理这样的链接请求过来的。后端提供的接口就是叫xxx.gif?还是这就是一张图片的请求,那后端怎么拦截?

拦截?
发送的链接请求都会被记录在服务器的日志文件里面,后端对日志文件进行分析,获取每条打点请求携带的参数数据。
一般返回都是空的头部header。

@ManyDai
Copy link

ManyDai commented Jan 3, 2020

题目都没看明白。流下了菜比的眼泪

@cutie6
Copy link

cutie6 commented May 14, 2020

补充楼上~以下为参考了网上资料后的一些个人整理:

  1. 能够完成整个 HTTP 请求+响应(尽管不需要响应内容)
  2. 触发 GET 请求之后不需要获取和处理数据、服务器也不需要发送数据
  3. 跨域友好
  4. 执行过程无阻塞
  5. 相比 XMLHttpRequest 对象发送 GET 请求,性能上更好
  6. GIF的最低合法体积最小(最小的BMP文件需要74个字节,PNG需要67个字节,而合法的GIF,只需要43个字节)

参考资料:
SegmentFault 上的回答
Web beacon
Using a Beacon Image for GitHub, Website and Email Analytics
为什么前端监控要用 GIF 打点

最低合法体积是什么意思

@xgqfrms
Copy link

xgqfrms commented Sep 2, 2020

为什么 1px gif 字节大小有的是 43 bytes, 有的是 42 bytes?

43 bytes

https://mercury.jd.com/log.gif

image

42 bytes

https://commons.wikimedia.org/wiki/File:Transparent.gif

image

@menhal
Copy link

menhal commented Jun 8, 2021

我理解是因为技术惯性. 其实ajax也没问题, 反正就算跨域请求也能发出去(只是浏览器收不到返回值而已)

@shifengdiy
Copy link

  1. 请求体足够小,不需要回应
  2. img天然跨域,不会阻塞ajax请求
  3. 相比ajax性能更好,不会对页面有任何影响

@lson-lee
Copy link

lson-lee commented Sep 22, 2021

最近埋点遇到了一个问题,不知道大家有没有遇到过:

  1. 使用 img 方式发送埋点
  2. 点击后触发埋点并跳转页面

这个时候,如果是「chrome 浏览器」并且「打开控制台」,就会出现:
network 中只有一条网络请求,但是抓包工具和埋点接收方都显示有两条请求,内容完全一致

@Bibooo25730
Copy link

这题脑壳有问题?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests