统计上报---日志上报成功率高的方式

2,823 阅读4分钟

1、使用图片信标

这项技术非常类似动态脚本注入. 使用JavaScript创建一个新的Image对象, 并把src属性设置为服务器上的脚本URL. 该URL包含了我们要通过GET传回的键值对数据. 请注意并没有创建img元素或把它插入DOM.

1
2
3
4
5
var url = '/status_tracker.php';var params = [
'step=2',
'time=1248027314'
]
(new Image()).src = url + '?' + params.join('&');

服务器会接收到数据并保存下来, 它无需向客户端发送任何回馈消息, 因此没有图片会实际显示出来. 这是给服务器回传信息最有效的方式. 它的性能消耗很小, 并且服务端的错误完全不会影响到客户端.

图片信标很简单, 但也意味着它能做的事情是有限的. 你无法发送POST数据, 而URL的长度有最大值, 所以你可以发送的数据的长度被限制得相当小. 你可以接收服务器返回的数据, 但只局限于非常少的几种方式. 一种方式是监听Image对象的load事件, 它会告诉你服务器是否成功接收数据. 你还可以检查服务器返回的图片的宽度和高度(如果是图片的话)并使用这些数字通知你服务器的状态. 举个例子, 宽度为1表示”成功”, 为2表示”重试”.

如果你不需要在响应中返回数据, 就应该发送一个不带消息正文的204 No Content状态码, 它将阻止客户端继续等待永远不会到来的消息正文.

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var url = '/status_tracker.php';var params = [
'step=2',
'time=1248027314'
]
var beacon = new Image();
beacon.src = url + '?' + params.join('&');
beacon.onload = function( ) {
if (this.width == 1) { //成功
} else if (this.width == 2) { //失败
}
}
beacon.onerror = function() {
//出错
}

2. navigator.sendBeacon

js sendBeacon

页面性能日志:

DNS解析耗时 TCP链接耗时 SSL安全链接耗时 网络请求耗时 DOM解析耗时 资源加载耗时 首包时间 白屏时间 首次可交换时间 Dom Ready时间 页面完全加载时间。

如某些统计系统,在页面unload时,如果要上报当前数据,采用xhr的同步上报方式,会阻塞当前页面的跳转;使用new Image有可能遇到aborted,导致无法成功发送。

现在好了,可以使用浏览器来提供发送保障的更简洁的sendBeacon方法。sendBeacon是异步的,不会影响当前页到下一个页面的跳转速度,且不受同域限制。

window.addEventListener('unload', logData, false);

function logData() {
    navigator.sendBeacon("/log", analyticsData);
}

sendBeacon 如果成功进入浏览器的发送队列后,会返回true;如果受到队列总数、数据大小的限制后,会返回false。返回ture后,只是表示进入了发送队列,浏览器会尽力保证发送成功,但是否成功了,不会再有任何返回值。目前暂无具体的数据长度限制标准。

考虑到对目前浏览器的支持情况,需要做一下降级支持(如同步模式下的xhr,如果不是同域则要支持CORS):

navigator.sendBeacon || new Function('var xhr=new XMLHttpRequest();xhr.open("POST",arguments[0],true);r.send(arguments[1]);');

当前浏览器对sendBeacon的支持情况(最新进展见:caniuse.com/#search=sen…):

  • Chrome 37+
  • Firefox (Gecko) 31+
  • Internet Explorer 不支持
  • Opera 24+
  • Safari 不支持
  • 手机端常用浏览器不支持
    :Android浏览器支持了,但是iOS尚无支持

Google Analytics已经使用了navigator.sendBeacon()来上报数据:www.thyngster.com/google-anal…


3、IE8下的跨域共享

XDomainRequest 是代表javascript和Ajax的跨域请求

IE8+可使用XDomainRequest进行跨域请求

Members组成

XDomainRequest包含以下几部分:

1.事件

2.方法

3.属性

Events事件

1)onerror事件:完成跨域请求过程中发生错误时,会被激发

2)onload事件:成功请求完毕,返回对象时,会被激发

3)onprogress事件:浏览器开始从服务器端接收数据时,会被激发

4)ontimeout事件:超时会被激发

Methods方法

1)abort方法:终止等待send

2)open(XDomainRequest)方法:建立与服务器的链接

3)send(XDomainRequest)方法:传输一个字符窜数据给服务器来进行处理

Properties属性

1)constructor属性:返回一个对象的构造函数的引用

2)contentType属性:返回html请求或者返回的头部的content-type属性

3)responseText属性:以字符窜形式返回请求的body内容

4)timeout属性:超时返回的值


Usage用法

//创建一个对象

var xdr = new XDomainRequest();

//以get的方式建立链接

xdr.open("get", "http://www.contoso.com/xdr.aspx");

//发送数据给服务器

xdr.send();
Example例子