关于数据:数据上报方式是否存在最优解

45次阅读

共计 4494 个字符,预计需要花费 12 分钟才能阅读完成。

1. 前言

最近神策数据 Web JS SDK 默认的数据上报形式由原来的 image 改成了 beacon。其实 image 只是数据上报形式中的一种,它是通过向服务端发送图片申请来实现数据传输的,还有另外两种向服务端发送数据的形式:ajax 和 beacon。

上面针对神策数据 Web JS SDK 数据上报形式进行具体的介绍,心愿能给大家提供一些参考。

2. image

image 形式是通过将采集的数据拼接在图片申请的前面,向服务端申请一个 1*1 px 大小的图片实现的,设置它的 src 属性就能够发送数据。这种形式简略且人造可跨域,又兼容所有浏览器,没有阻塞问题,是目前比拟受欢迎的前端数据上报形式。但因为是 get 申请,对上报的数据量有肯定的限度,个别为 2~8 kb。代码示例如下:

var img = new Image();img.width = 1;img.height = 1;img.src = ‘/sa.gif?project=default&data=xxx’;

2.1. crossOrigin 属性

HTML5 给 <img> 标签新减少了一个 crossOrigin 属性,这个属性决定了图片获取过程中是否开启跨域性能。并且如果设置了 crossOrigin 这个属性,image 申请中将不带 cookie。代码示例如下:

浏览器端设置:

var img = new Image();
img.crossOrigin = “anonymous

服务端设置:

set(‘Access-Control-Allow-Origin’, ‘*’);

设置了 crossOrigin = “anonymous” 的后果如图 2-1 所示:

图 2-1 设置了 crossOrigin = “anonymous”

未设置 crossOrigin = “anonymous” 的后果如图 2-2 所示:

图 2-2 未设置 crossOrigin = “anonymous”

如果只是在客户端设置了 crossOrigin,服务端没有设置跨域,申请图片将失败!

如果 canvas 加载了不同域的图片,就会变成被净化的画布,此时为了平安思考,就不能再应用 getImageData()、toBlob()、toDataURL() 办法了。应用 crossOrigin 时,能够设置资源依照 CORS 来申请,这样 canvas 就不会辨认出资源的跨域问题。

2.2. image 形式发送

Web JS SDK 将用户在 Web 页面的行为比方页面浏览、元素点击、视区停留等上报给服务端。先将采集数据用 JSON 编码为字符串,再通过拼接 data 参数传递给服务端。发送的形式是 get,最初由服务端对立解决。在 Network 中能够看到一个带有 sa 字段的 gif 申请,就是神策 Web JS SDK 发送的 image 申请,如图 2-3 所示:

图 2-3 image 形式发送数据

3. ajax

在 JavaScript 中,XMLHttpRequest 是客户端的一个 API,它为浏览器与服务端通信提供了一个便捷通道。古代浏览器都反对 XMLHttpRequest API,如 IE 7+、Firefox、Chrome、Safari 和 Opera 等。这种形式发送数据相对来说比较简单,应用 post 形式能够发送大量的数据。默认发送形式是异步,不会阻塞页面,但会占用肯定的客户端资源,且须要非凡解决跨域限度。代码示例如下:

function

 createXHR(){

    return

 window.XMLHttpRequest?

    new XMLHttpRequest():    new ActiveXObject(“Microsoft.XMLHTTP”);}var xhr = createXHR();  // 实例化 XMLHttpRequest 对象 xhr.open

 (“post”, url , true);  // 建设连贯

xhr.send(data);  // 发送申请

. credentials 属性

古代的 XMLHttpRequest 反对跨域申请,且跨域申请默认不携带 cookie。credentials 默认值是 false,示意默认状况下不带 cookie。如果跨域申请要带 cookie 的话,须要满足上面三个条件:

浏览器端设置:

服务端设置:

浏览器设置中,没有敞开第三方 cookie 性能。

3.2. ajax 形式发送

将采集数据用 JSON 编码为字符串,再通过 XMLHttpRequest 的 send 办法发送 data 给服务端,发送的形式是 post,最初由服务端对立解决。在 Network 中能够看到一个带有 sa 字段的 xhr 申请,就是神策 Web JS SDK 发送的 ajax 申请,如图 3-1 所示:

图 3-1 ajax 形式发送数据

4. beacon

navigator.sendBeacon 是一个比拟新的 API,它是指浏览器通过异步的 post 形式发送数据到服务端。该办法在页面跳转、刷新、敞开页面时发送申请,能够保证数据发送不易失落,浏览器会对其进行调度以保证数据无效送达,并且不会阻塞页面的加载或卸载。不受跨域限度,浏览器兼容性较好,能够反对除 IE 之外的简直所有浏览器。具体应用办法如下:

url:data 将要被发送到的网络地址;

data:将要发送的 ArrayBufferView、Blob、DOMString 或者 FormData  类型的数据;

返回值:当用户代理胜利把数据退出传输队列时,sendBeacon() 办法将会返回 true,否则返回 false。

sendBeacon 容许开发者通过 post 申请发送大量数据到服务端,它的特点很显著:

在浏览器闲暇的时候异步发送数据,不影响页面诸如 JS、CSS Animation 等执行;

页面在 unload 状态下,也会异步发送数据,不阻塞页面刷新和跳转等操作;

可能被客户端优化发送,尤其在 Mobile 环境下,能够将 beacon 申请合并到其余申请上一起解决;

只能判断出是否放入浏览器工作队列,不能判断是否发送胜利。

4.1. 兼容性

如图 4-1 可见以后浏览器对 sendBeacon 的反对状况:

图 4-1 sendBeacon 兼容性(图片来源于 MDN)

尽管古代浏览器对 sendBeacon 的反对很好,但也须要做兼容性解决。Web JS SDK 会判断用户以后设施是否反对 sendBeacon,如果不反对,就会走 image 形式将数据发送进来。比方初始化代码配置了 send_type:’beacon’,而用户的浏览器不反对 navigator.sendBeacon 办法,则 Web JS SDK 会主动转而应用 image 形式发送数据。代码解决办法如下:

if

 (sendType === ‘beacon’ && typeof navigator.sendBeacon !== “function”) {

    sendType = ‘image’;}

留神:在 iOS 11.1-12 上 sendBeacon 发送申请到一个之前未拜访过的域名会失败,iOS 13 修改了这个问题。详情可见文档:https://caniuse.com/?search=s…

4.2. 发送数据大小限度

目前没有给出具体的发送数据大小限度规范,不过有人做了上面的测试:当数据是 65536 字符长度时,异步申请进入浏览器发送队列失败,代表数据大小是有限度,不一样的浏览器应该有所差别。测试代码如下:var url = ‘http://jsfiddle.net?sendbeacon’;var n = 65536; //

 sendBeacon limit for Chrome v40 on Windows (2^16)

var data = new Array(n+1).join(‘X’); //

 generate string of length n

 

if(!navigator.sendBeacon(url, data)){alert(‘data limit reached’);}

具体参考:http://www.voidcn.com/article…

4.3. beacon 形式发送

将采集数据用 JSON 编码为字符串,再通过 XMLHttpRequest 的 send 办法发送 data 给服务端,发送的办法是 post,最初由服务端对立解决。在 Network 中能够看到一个带有 sa 字段的 ping 申请,就是神策 Web JS SDK 发送的 beacon 申请,如图 4-2 所示:

图 4-2 beacon 形式发送数据

5. 演进过程

下面咱们别离对三种数据上报形式进行了介绍,上面从多个角度来剖析 image、ajax、sendBeacon 的优缺点,如表 5-1 所示:

表 5-1 发送形式比照

5.1. 第一版

神策数据 Web JS SDK 第一版发送形式抉择的是 image,采纳 image 形式的长处如下:

应用形式简略;

人造可跨域;

浏览器兼容性好。

当然,image 形式也存在毛病:

敞开页面时发送数据成果较差;

对上报的数据量有肯定的限度,个别为 2~8 kb;

很容易被一些浏览器图片加载器拦挡,之前咱们有过相干的介绍:https://mp.weixin.qq.com/s/EE…。

5.2. 第二版

因为 image 形式敞开页面时发送数据成果较差,因而 SDK 减少了缓存模式,发送形式抉择了批量发送。长处如下:

当数据产生后会先将数据存储在 localStorage 中,达到发送条件后才会把存储在 localStorage 中的数据合并发送进来;

如果数据发送不胜利,会将发送的数据保存起来,满足发送条件后,与之后的数据一起尝试发送。

当然,缓存模式也存在毛病:

localstorage 遵循浏览器同源策略,即便子域名 localstorage 也不能共享;

可能会呈现数据提早上报和跨子域数据不发送的景象。

5.3. 第三版

因为缓存模式中子域名 localstorage 不能共享,因而抉择了 beacon 作为新的发送形式,通过异步的 post 形式发送数据到服务端。长处如下:

不受跨域限度;

页面刷新和跳转时发送数据体现较好。

当然,beacon 形式也存在毛病:不兼容 IE 等局部浏览器。

为了解决这一问题,在不反对 navigator.sendBeacon 办法的浏览器中,Web JS SDK 会主动转而应用 image 形式发送数据。

6. 总结

通过后面的介绍能够看出,没有一种数据上报形式在各个方面都是优良的,都有肯定的优缺点。因而,面对不同的需要时,咱们要抉择不同的形式来上报数据:

如果发送数据量较小,比方采集用户在 Web 页面的页面浏览、元素点击、视区停留等行为事件,采纳 image 形式上报给服务端更适合;

如果发送数据量较大,比方获取后端所有数据用于前端渲染,ajax 形式更适合;

如果须要进行准确统计,比方点击领取按钮、视频播放时长、页面跳转或敞开等行为时,抉择 beacon 形式能最大水平保证数据成功率。

对于神策数据 Web JS SDK 而言,咱们为了最大水平上保证数据的可靠性,优先应用 beacon 形式来上报数据。在浏览器不反对 beacon 的状况下,Web JS SDK 主动转而应用 image 形式来上报。

文章起源:公众号 - 神策技术社区

正文完
 0