数据采集:前端数据上报的方式有哪些

@GuoYongfeng 2018-12-06 08:08:48发表于 iuap-design/blog

1、xhr 异步上报

异步请求,发送数据到后端。但是受到跨域、同源的限制。

HttpRequestTools.xhr = function (url, data) {
    data = applyHttpOptions(data);
    const xhr = new XMLHttpRequest;
    xhr.open("POST", url, !0);
    try {
        if ("withCredentials" in xhr) {
            xhr.withCredentials = true;
        }
    } catch (r) {
    }
    xhr.setRequestHeader("content-type", "text/plain");
    xhr.send(data);
    return xhr;
};

2、jsonp 跨域上报

解决异步请求的跨域问题,但是对后台服务也是有要求的。

HttpRequestTools.jsonp = function (url, data, callback) {
    data = applyHttpOptions(data);
    const script = document.createElement("script");
    script.type = "text/javascript";
    script.src = url + "&jsonp=" + callback;
    const ins = document.getElementsByTagName("script")[0];
    ins.parentNode.insertBefore(script, ins);
    return script;
};

3、使用 new Image 通过 GIF 图片上报

javascript 请求后端脚本常用的方法是 ajax,但是ajax 是不能跨域请求的。一种通用的方法是 js 脚本创建一个 Image 对象,将 Image对象的 src 属性指向后端脚本并携带参数,此时即实现了跨域请求后端。这也是后端脚本为什么通常伪装成 gif 文件的原因。

HttpRequestTools.img = function (data) {
    data = applyHttpOptions(data);
    let url = yy_rum.server.beacon_img();
    url += "&data=" + encodeURI(encodeURI(data));
    const img = new Image;
    img.src = url;
    return img;
};

4、使用浏览器的 navigator.sendBeacon 上报

navigator.sendBeacon() 方法主要用于满足 统计和诊断代码 的需要,这些代码通常尝试在卸载(unload)文档之前通过HTTP将少量数据异步传输到Web服务器。

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

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

HttpRequestTools.beacon = function (data) {
    data = applyHttpOptions(data);
    let url = yy_rum.server.beacon();
    return navigator.sendBeacon(url, data);
};

浏览器兼容情况:

image

上报策略优先级选择

1、浏览器支持 navigator.sendBeacon 的话,首选;
2、不支持的话,用 Gif 图片。

参考资料