前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >GA源代码里的小技巧之Beacon请求

GA源代码里的小技巧之Beacon请求

作者头像
mmzhou
发布于 2018-08-01 10:47:45
发布于 2018-08-01 10:47:45
1.3K00
代码可运行
举报
文章被收录于专栏:前端小作坊前端小作坊
运行总次数:0
代码可运行

GA源代码里的小技巧之Beacon请求

作者前段时间在做类似Google Analytics(以下简称GA)的第三方监控脚本。所以对GA的前端代码做过调研,对GA的压缩后代码做了一定程度上的人肉美化。这里美化的是analytics.js的j41版本,本文提到的小技巧也是基于这个版本的js。

智能Beacon

GA监控脚本一般都放在开发者的网页上。域名往往和Google不一样,这样发送请求到Google服务器的时候会涉及到跨域。普通的Ajax请求是做不到的,通常称这种请求为beacon或是ping。业内常用的一个方案是发送一个图片请求(GET方式),将请求参数放在图片请求的地址后面。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.google-analytics.com/r/collect?v=1&_v=j46&a=134081920&t=pageview&_s=1&dl=http%3A%2F%2Fzencode.in%2F&ul=zh-cn&de=UTF-8&dt=MZhou%27s%20blog%20-%20Taste%20of%20life.&sd=24-bit&sr=1280x800&vp=481x676&je=0&fl=22.0%20r0&_utma=9582782.1438874051.1425021219.1431473728.1471631422.8&_utmz=9582782.1471631422.8.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)&_utmht=1473782171819&_u=QACCAAABI~&jid=633265686&cid=1438874051.1425021219&tid=UA-36422454-1&_r=1&gtm=GTM-MP42BH&z=300649187

因为通常第三方监控请求没有很强的安全要求(不会发送密码、密钥之类的信息),所以使用图片请求将请求参数放在地址里面也是OK的。示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function imgPing(url, callback) {
    var key = '__SOME_RANDOM_KEY__' + (+new Date());
    var img = new Image();
    window[key] = img;
    img.onload = img.onerror = img.onabort = function () {
        img.onload = img.onerror = img.onabort = null;
        window[key] = null;
        img = null;
        if (callback) {
            callback();
        }
    };
    img.src = concatUrl;
    return true;
}

图片请求是GET请求,参数放在URL地址中,而URL地址的长度是有一定限制的。规范对URL长度并没有要求,但是浏览器、服务器、代理服务器都URL对长度有要求。例如:IE6、7、8(部分)的URL长度不能超过2083的字符长度,URL中的path部分不能超过2048。这就导致有些请求会发送不完全。

为了解决这个问题可以使用XMLHttpRequest(简称XHR)来发送跨域POST请求。当然这需要浏览器的跨域支持。发送POST请求时,参数都放在请求的payload中,不会受到URL长度所限制。但因为是POST请求,所以需要协议头部比GET方法多一点点,消耗也稍高。示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function xhrPing(url, params, callback) {
    if (hasCors()) {
        return;
    }

    var xhr = new window.XMLHttpRequest();
    xhr.open('POST', url, true);
    xhr.withCredentials = true;
    xhr.setRequestHeader('Content-Type', 'text/plain');
    if (callback) {
        xhr.onreadystatechange = function () {
            if (xhr.readyState !== 4) {
                return;
            }

            var status = xhr.status;
            var isSuccess = status >= 200 && status < 400;
            var error = null;
            if (!isSuccess) {
                error = new Error();
            }
            callback(error);
        };
    }
    xhr.send(params);
};

除了这两种方法之外,浏览器还提供了一个标准的用于发送beacon的方法:[navigator.sendBeacon](http://)。这个方法本质上和跨域的XHR请求没有多大区别,但是sendBeacon方法能够确保在页面关闭的时候还能发送成功。这也是它的最大优势。示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function beaconPing(url, params) {
    if (hasSendBeacon()) {
        return window.navigator.sendBeacon(url, params);
    }
    else {
        return false;
    }
};

sendBeacon出现之前,为了能够在页面关闭时发送beacon,常用的方法是两种:

  1. 先发送一个图片的beacon,然后死循环200ms左右来提高beacon请求发送成功的概率
  2. 发送同步的XHR请求,确保页面要等到XHR请求结束后才能关闭。不过同步XHR已经被W3C标准定义为不推荐使用了: Synchronous XMLHttpRequest outside of workers is in the process of being removed from the web platform as it has detrimental effects to the end user's experience. (This is a long process that takes many years.) Developers must not pass false for the async argument when entry settings object's global object is a Window object. User agents are strongly encouraged to warn about such usage in developer tools and may experiment with throwing an InvalidAccessError exception when it occurs.

综合上面的讨论给出如下的对比表格:

方法

优点

缺点

图片请求

1. GET请求头部少,快2. 支持广

1. URL长度限制2. 需要延迟关闭才能用于unload发送

sendBeacon

1. unload时更能确保成功2. 支持发送更多数据

1. POST请求消耗多2. 旧浏览器支持少

XHR CORS

支持发送更多数据

1. POST请求消耗多2. 旧浏览器支持少3. unload时不能使用

如果没有指定发送方法,那么GA会在URL字符长度不超长时使用图片beacon的方式发送。如果超过了则尝试使用sendBeacon方法发送beacon请求,如果不支持sendBeacon则会采用跨域XHR发送。如果跨域XHR不支持则最后fallback到图片发送。实际代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var smartPing = function(api, param, callback) {
    callback = callback || noop;
    if (2036 >= param.length) {
        imgPing(api, param, callback);
    } else if (8192 >= param.length) {
        beaconPing(api, param, callback) || xhrPing(api, param, callback) || imgPing(api, param, callback);
    } else {
        errorPing('len', param.length);
        throw new OverLengthError(param.length);
    }
};

当然GA的做法并非最优,因为非IE6、7的浏览器图片请求发送的数据可以超过2083。如果真的有很多数据需要发送,那么我们可以合并短请求、拆分长请求。

资料:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
GA源代码里的小技巧之cookie篇
cookie的本质是存储在浏览器端的一段简单数据(多个键值对),浏览器会从服务器接受或者发送给服务器cookie。这样便可以为没有状态的HTTP协议提供了记录状态信息的方法,知道多个不同的HTTP请求是否来自同一个浏览器。
mmzhou
2018/08/01
1.7K0
GA源代码里的小技巧之cookie篇
AJAX和JSON
open方法不会向服务器发送真正请求,它相当于初始化请求并准备发送只能向同一个域中使用相同协议和端口的URL发送请求,否则会因为安全原因而报错。
乐心湖
2021/01/18
2.6K0
AJAX和JSON
前端页面统计beacon调研
注意xhr.open('post', '/log', false)的第三个参数, false为同步请求,也就是document unload之前必须等待请求发出并响应; true表示异步请求,在document unload时容易被浏览器遗弃。
用户1217459
2019/07/10
7890
前端页面统计beacon调研
浅析前端监控技术
但是会发现根本没有收到消息,因为我们发的是异步的请求,请请求发出去之前当前页面的上下文环境已经被销毁了,因此什么也发不出去。
码之有理
2023/04/14
9580
前端埋点数据收集及上报方案
埋点,它的学名是事件追踪(Event Tracking),主要是针对特定用户行为或业务过程进行捕获、处理和发送的相关技术及实施过程。埋点是数据领域的一个专业术语,也是互联网领域的一个俗称。
落落落洛克
2021/10/12
6.9K0
【Go 语言社区】js 向服务器请求数据的五种技术
Ajax,在它最基本的层面,是一种与服务器通讯而不重载当前页面的方法,数据可从服务器获得或发送给服务器。有多种不同的方法构造这种通讯通道,每种方法都有自己的优势和限制。 有五种常用技术用于向服务器请求数据: (1)XMLHttpRequest (XHR) (2)动态脚本标签插入 (3)框架 (4)Comet (5)多部分的XHR 在现代高性能JavaScript中使用的三种技术是XHR,动态脚本标签插入和多部分的XHR。使用
李海彬
2018/03/20
2.3K0
网站数据统计分析之二:前端日志采集是与非
在上一篇《网站数据统计分析之一:日志收集原理及其实现》中,咱们详细的介绍了整个日志采集的原理与流程。但是不是这样在真实的业务环境中就万事大吉了呢?事实往往并非如此。比如针对前端采集日志,业务的同学经常会有疑问:你们的数据怎么和后端日志对不上呢?后端比你们多了 N%!技术的同学也会问:你们怎么不打后端记日志呢?后端比你们效率和准确性更高。带着这些疑问今天咱们就来聊聊前端日志采集中的这些是是非非。 1、前端 VS 后端到底哪个准?该用谁? 这应该算是统计分析同学最为关注的问题之一了,到底哪个准我们应该从技术和业
用户1177713
2018/02/24
2.5K0
ajax跨域的基本流程
创建XMLHttpRequest对象,也就是创建一个异步调用对象;判断XHR对象属性;创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息;设置响应HTTP请求状态变化的函数;发送HTTP请求;获取异步调用返回的数据;使用JavaScript和DOM实现局部刷新。
行云博客
2020/07/13
9100
文件上传那些事儿
导语 作为一枚初入鹅厂的鲜鹅,对这里的一切都充满着求知欲。看到我们的KM平台如此生机勃勃,各种技术分享交流如火如荼,在努力的汲取着养分的同时也期待自己能为这个生态圈做出贡献。正好新人导师让我看看能否把
谭伟华
2017/05/04
10.7K5
Web Beacon 刷新/关闭页面之前发送请求
本文中提到的链接,因为微信的限制,没有显示出来,查看文中链接,需要点击最下方的阅读原文链接
OBKoro1
2020/10/27
1.7K0
Web Beacon 刷新/关闭页面之前发送请求
前端埋点上报的几种方式
在现代Web应用程序中,埋点上报是一种重要的数据收集和分析手段。本文将介绍前端埋点上报的几种常见方式,并详细阐述如何在项目中运用这些方式进行数据上报,以帮助开发者更好地进行数据收集和分析。
can4hou6joeng4
2023/11/16
1.5K0
Ajax第一节
异步: 不受当前任务的影响,两件事情同时进行,做一件事情时,不影响另一件事情的进行。
用户3461357
2019/08/02
3.9K0
CSRF攻击原理介绍和利用
注意:本文分享给安全从业人员,网站开发人员和运维人员在日常工作中使用和防范恶意攻击,请勿恶意使用下面描述技术进行非法操作。
全栈工程师修炼指南
2020/10/23
4.6K0
CSRF攻击原理介绍和利用
一个兼容get请求和post请求的Ajax封装函数
今天在看某风网老师录制的 Ajax 函数封装的视频,get 和 post 请求都考虑到了,我在这里也做一下笔记。
德顺
2019/11/12
1.6K0
原生AJAX请求教程
ajax 即 Asynchronous Javascript And XML,AJAX 不是一门的新的语言,而是对现有持术的综合利用。本质是在 HTTP 协议的基础上以异步的方式与服务器进行通信.
老马
2018/07/31
2.7K0
使用 WEB API Beacon 记录行为日志 (译)
原文: Logging Activity With The Web Beacon API;
腾讯IVWEB团队
2020/06/28
1.6K0
国庆节前端技术栈充实计划(5):JavaScript SDK设计指南
SDK是软件开发工具包 的缩写,是能够让编程者开发出应用程序的软件包。一般SDK包括一个或多个API、开发工具集和说明文档。
疯狂的技术宅
2019/03/27
2.1K0
国庆节前端技术栈充实计划(5):JavaScript SDK设计指南
原生——ajax
什么是Ajax?(前后端数据交互) Asynchronous JavaScript and XML(异步JavaScript和XML)
FinGet
2019/06/28
2K0
【JS】1680- 重学 JavaScript API - Beacon API
Beacon API 是 HTML5 提供的一种新的浏览器 API,可以用于在浏览器后台异步地发送数据,而不影响当前页面的加载和性能。通过 Beacon API,开发者可以在「页面卸载或关闭时」,「将数据发送给服务器」,从而实现一些监控和日志等功能。
pingan8787
2023/09/01
3070
【JS】1680- 重学 JavaScript API - Beacon API
让前端监控数据采集更高效
随着业务的快速发展,我们对生产环境下的问题感知能力越来越关注。作为距离用户最近的一层,前端的表现是否可靠、稳定、好用,很大程度上决定着用户对整个产品的体验和感受。因此,对于前端的监控不容忽视。
桃翁
2019/05/31
1.4K0
相关推荐
GA源代码里的小技巧之cookie篇
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文