本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
点击上方 程序员成长指北,关注公众号
回复1,加入高级Node交流群前端日志采集,说简单也简单,说复杂也复杂,取决于业务想要什么粒度的数据,以及开发者能接受多少侵入性、延迟和兼容性问题。今天我们就来盘一盘常见的几种前端上报方式,以及各自的优劣势和适用场景。
1. + GIF / Pixel 上报
原理: 通过在页面上动态创建一个Image对象,把要上报的数据编码到请求 URL 的 query 参数中,然后加载一个 1x1 的透明 GIF 图片(当然不需要真的返回一张图,后端 204 也行),重点是通过 src 请求资源的同时,让服务端记录. gif 后的数据。
代码示例:
const img = new Image();
img.src = `https://logserver.com/collect?event=click&userId=123`;优点:
兼容性超好,从古早 IE 到现代浏览器都能用。
不受 CORS 限制,因为图片加载天然跨域。
简单,几乎不会影响页面性能。
缺点:
请求量小,受 URL 长度限制(一般 2KB 左右)。
只能 GET,不能 POST。
无法拿到发送成功或失败的准确回调。
适用场景:
简单 PV/UV 打点,曝光上报。
无需保证必达,只要发出请求就行。
2. fetch / XMLHttpRequest 上报
原理: 使用fetch或者XMLHttpRequest直接发 HTTP 请求,数据格式可以是 JSON 或表单数据,GET/POST 都行。
代码示例:
js
体验AI代码助手
代码解读
复制代码
// fetch版
fetch('https://logserver.com/collect', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event: 'click', userId: 123 })
});优点:
可以 POST,支持大体积数据。
可以拿到请求成功或失败的反馈。
灵活,能带复杂头部,比如认证信息。
缺点:
受 CORS 限制,需要服务器支持。
发送过程中可能阻塞主线程,尤其是同步 XHR。
如果页面关闭得太快,可能请求还没发出去(不过可以用
keepalive选项优化)。
适用场景:
错误日志、性能埋点。
需要可靠上报、需要认证或者复杂参数时。
3. navigator.sendBeacon
原理: 专门为这种场景设计的 API,可以在页面卸载(比如跳转、关闭)时,异步且可靠地把数据发送到服务器,不阻塞页面卸载流程。
代码示例:
navigator.sendBeacon('https://logserver.com/collect', JSON.stringify({ event: 'unload', userId: 123 }));优点:
适合页面关闭前发送数据,不容易丢包。
不阻塞 unload 流程,不卡界面。
支持 POST,发送简单。
缺点:
兼容性略差(但现在主流浏览器基本都支持了)。
不支持自定义请求头。
只支持 Content-Type 是
application/x-www-form-urlencoded或text/plain的请求体。
适用场景:
- 页面 unload 时的上报,比如用户行为日志、退出日志。
4. WebSocket 上报
原理: 建立长连接,把日志实时推送到服务器。
优点:
实时性超强。
理论上吞吐量高,连接一旦建立数据传输非常轻量。
缺点:
建连、保活有成本,移动端或弱网环境下容易掉线。
服务端也要有能力管理大量持久连接。
不适合小流量、轻量应用。
适用场景:
- 高实时要求的埋点,比如游戏、IM、股票类应用。
总结
实际开发里,我们会根据业务场景,多种方式结合使用:普通打点用fetch,页面 unload 用sendBeacon,曝光用Image兜底,再加一些重试机制,做到不丢、不卡、可靠。
Node 社群
我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。
“分享、点赞、在看” 支持一波👍