[译] 用 sendBeacon 发送分析信息的优点

本文探讨了使用sendBeacon API发送分析信息的好处,包括无需响应、简化跨域资源共享、提高请求优先级、改进页面卸载时的行为等。此外,还讨论了如何克服请求成功状态反馈的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

7e083da48e6f8e49f2cebb3176cb919d.png

在实践中,我们使用 HTTP 请求将一些匿名指标从浏览器发送到服务器端。这些收集来的信息用于验证应用的行为是否正常、监控其质量和速度、服务恶化时发出警告等,也有助于通过统计分析和研究改善平台服务质量。

最近我们开始使用 sendBeacon API 来取代 XMLHttpRequests 完成以上任务。在本文中,我们将细数一些从此次转换中带来的好处。

sendBeacon 功能简介

sendBeacon 以一种将分析信息回传给服务端而无需响应的方式被创建出来。这种专注的设计目的和需要考虑行为、安全、性能和优先级的 XHR 有巨大的不同,这些稍后会详述。

首先值得强调的是其不需要响应的显著特性。当浏览器需要来自 web 服务器的响应时,就意味着应用可能会依照得到的信息行事 -- 这也是为何浏览器厂商们要实现某些防御机制以保护用户的原因,因而 sendBeacon API 也得以不受那些相同的约束。

下面的 Chrome Network 面板截图展示了截获的从 XHR 转向 sendBeacon 工作中,发往监控服务的请求。sendBeacon 请求被描述为 “ping” 类型,可以看到各种请求和它们之间的区别。

9677ddfd97941ee2b37fed7ba1fe363a.png

跨域资源共享 (CORS)

CORS 规定了一个域间(或子域间)发送数据的复杂协议,包含一个预检 OPTIONS 请求及默认不发送相关 cookie 头等策略。考虑到分析信息常被发送到不同的子域甚至完全跨域,这些限制还是必要的。

可以在 Network 面板中看到和每个 XHR 请求相伴而生的预检请求,也能发现 XHR 请求忽略了整个 cookie 头;而 sendBeacon 请求则没有这些限制 -- 不用预检请求,也携带了 cookie 头。

优先级

一旦浏览器能感知到某些请求是无关用户体验的,就能分出轻重缓急了,和用户体验相关的请求会被优先执行完毕。

在 Network 页签的 Priority 列中,这些请求的不同显而易见。

行为

因为 sendBeacon 请求无需响应,浏览器也就不用像对待 XHR 或 fetch 那样,每当页面一 unload 就得中断它们。Network 页签中包含了一个 status 和 time 列都为 (unknown) 的请求。该请求就是页面切换之前被执行而没来得及中断的;当下一个页面的请求被处理完后,浏览器才在后台将其完成了。

下面展示的,是一个发送页面有效期内累计指标的例子。我们在页面的生命周期内收集信息,并在页面可见性改变为隐藏时发送这些信息。这一事件发生在用户切换页签之时 -- 以及至关重要的是,在页面跳走并 unload 之前发生。这同时意味着你可以并行不悖地发送信息和跳转链接。

下图展示了这一特性如何增加了我们能够收集到的累积指标的数量。

492f5a87d2ebf5632114981b481c88f1.png

收到的累积指标的数量

限制

由于这个请求函数不接受响应,使得我们要设法让浏览器获知请求是否成功抵达服务端;这是切换到 sendBeacon 后为数不多需要应付的问题。通过函数返回值,我们将能够判断是否成功。

尽管 sendBeacon 规范 (https://www.w3.org/TR/beacon/#sec-sendBeacon-method) 没有规定数据大小,但浏览器厂商一般会限制请求体积,这样一来 sendBeacon 函数将在传输失败时返回 false ,反之则是 true

如果以上限制妨碍到了某些信息的收集,则 fetch 函数提供的 “keepalive” 选项,可以作为 sendBeacon 的一种 替代方案,该选项允许请求的存活长于页面。

在最后一个例子中,我对比了三种方法:

  1. 普通 fetch 请求

  2. 配置了 keepalive 的 fetch 请求

  3. beacon (ping)

3377f45134d0089e37e4070de45edb50.png

总结

sendBeacon 为通过 HTTP 发送分析信息而生,善以用之可以改善站点的用户体验并增加应用曝光度。

2a355a81861a3f2a895003f2287587e9.png

原文:https://medium.com/fiverr-engineering/benefits-of-sending-analytical-information-with-sendbeacon-a959cb206a7a

2a0790839763d4c6eb602b06f714faac.png1b2e06f9ea5b71ebe5463d460f9ccac4.png

### PyCharm 打开文件显示全的解决方案 当遇到PyCharm打开文件显示全的情况时,可以尝试以下几种方法来解决问题。 #### 方法一:清理缓存并重启IDE 有时IDE内部缓存可能导致文件加载异常。通过清除缓存再启动程序能够有效改善此状况。具体操作路径为`File -> Invalidate Caches / Restart...`,之后按照提示完成相应动作即可[^1]。 #### 方法二:调整编辑器字体设置 如果是因为字体原因造成的内容显示问题,则可以通过修改编辑区内的文字样式来进行修复。进入`Settings/Preferences | Editor | Font`选项卡内更改合适的字号大小以及启用抗锯齿功能等参数配置[^2]。 #### 方法三:检查项目结构配置 对于某些特定场景下的源码视图缺失现象,可能是由于当前工作空间未能正确识别全部模块所引起。此时应该核查Project Structure的Content Roots设定项是否涵盖了整个工程根目录;必要时可手动添加遗漏部分,并保存变更生效[^3]。 ```python # 示例代码用于展示如何获取当前项目的根路径,在实际应用中可根据需求调用该函数辅助排查问题 import os def get_project_root(): current_file = os.path.abspath(__file__) project_dir = os.path.dirname(current_file) while not os.path.exists(os.path.join(project_dir, '.idea')): parent_dir = os.path.dirname(project_dir) if parent_dir == project_dir: break project_dir = parent_dir return project_dir print(f"Current Project Root Directory is {get_project_root()}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值