Solo  当前访客:8 开始使用

如何保证页面卸载时的上报数据完整性


监控系统重要的一环是数据上报。

为了减少请求的次数,我们把一些细粒度的收集信息压入到内存中,等待触发一定规则后上报后台。

一般的规则是, 等待20s 或者 队列中的数据达到一定条数(如10条) 或者页面 unload时!

定时和定量的操作是没有问题的, 可以使用xhr或者其它任何交互方式,都可以轻松完成, 并保证数据的完整性!

然而,页面unload时,坑就多了,

1. 使用异步xhr

   这是最先使用的方式, 在chrome测试一切ok。 但是线上运行一段时间,发现数据丢失的现象。基本可以确定是浏览器行为导致的unload未成功执行异步xhr,

   解决方案: 在unload时加一个循环等待, 或者创建一个img并指定src, 通过资源加载的方式延迟关闭以保证异步请求正常发送

2. 异步不好使,试试同步xhr

  同步xhr,在现代浏览器已经不提倡使用, 同时同步的操作也会阻塞浏览器的关闭, 如果是reload,会造成用户体验问题, 并不是一个合适的解决方案, 但是可以作为备用

3. 杀手锏 sendBeacon

使用 sendBeacon() 方法会使用户代理在有机会时异步地向服务器发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能。这就解决了提交分析数据时的所有的问题:数据可靠,传输异步并且不会影响下一页面的加载。

BUT! 杀手锏毕竟是新玩意,对老古董还是没效的

注意点

chrome最新版本已不支持发送application/json格式的blob数据,会出现如下错误

Failed to execute 'sendBeacon' on 'Navigator': sendBeacon() with a Blob whose type is not any of the CORS-safelisted values for the Content-Type request header is disabled temporarily. See http://crbug.com/490015 for details.

可以改成使用以下三种

- application/x-www-form-urlencoded
multipart/form-data
text/plain
 

4. 如果不追求时效性, 自然是使用缓存+延时发送的策略最优雅, 同时丢失数据的问题也可以大大改善

 在unload或者beforeunload中,将数据写入localstorage (caniuse), 下次加载之前检查下是否有需要发送的数据, 有的话拿出来发送并清除数据

 

使用beacon demo如下:

 if(navigator && navigator.sendBeacon) {
                       var blob = new Blob([stringify(data)],
                               {type : 'text/plain'});
                       navigator.sendBeacon(this.endpoint, blob);
                   } else {
                       if(_window.XMLHttpRequest) {
                           var xhr = new XMLHttpRequest();
                           xhr.open("POST", this.endpoint, false);
                           xhr.setRequestHeader("content-type", "application/json")
                           xhr.send(stringify(data))
                       }
                   }

 

 =========================

19.08.05 测试

方式: 定时2min + 动态条数发送记录;sendBeacon+同步ajax兼容处理; unload超过2s,放入到localstorage;load时加载localstorage补发

验证测试数据, 数据丢失率高达6%

可能原因:

1. 由于合规问题,prod会前端重定向域名,导致补发可能未成功

2. 可能出现人为强制刷新,导致失败

3. 原先认为该数据只做补充,未在发送出加返回校验

解决方式:

加请求强校验,后端加冗余数据过滤

待测试效果验证~

======

 


标题:如何保证页面卸载时的上报数据完整性
作者:hugh0524
地址:https://blog.uproject.cn/articles/2019/03/12/1552404978819.html

, , , , 0 0