3

我正在构建一个类似于 Google Analytics 的平台,该平台使用非常标准的流程:

  1. 用户使用其独特的帐户参数获取和配置 JS 片段。
  2. 他们在他们的网站上嵌入了这个 JS 片段,它异步加载了我的主库。
  3. 库加载后,用户可以调用它的方法将数据发送到我的网络应用程序。

在研究了各种公司如何处理上述流程的几种不同实现之后,我发现 Google 的新Universal Analytics 标记似乎具有最优雅的执行方式,原因如下:

它似乎允许用户在主库仍在异步加载时进行方法调用,所有这些都在一个<script type="text/javascript">标签内。

这方面的一个例子是直接在快速入门代码

<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXX-Y', 'auto');
ga('send', 'pageview');

</script>
<!-- End Google Analytics -->

我试图了解它如何允许用户调用ga('create' ... )ga('send' ... )而主要的匿名函数可能仍在操纵 DOM 并插入/下载analytics.js脚本。

有人知道上述模式是如何工作的吗?

对他们的缩小代码进行逆向工程的尝试似乎表明他们可能正在创建一个空白ga对象,该对象有效地充当消息队列,直到主库加载。然后,当库加载时,它看起来正在解析队列对象并做它需要做的事情(因为如果库已经加载,它将能够实际执行其任务)。

我不能 100% 确定上述是否正确,因为对他们的所有代码进行逆向工程有点棘手。

我创建了一个类似的实现,其中我使用一个window.tempDataWhileLibraryHasntLoaded对象来存储由方法调用的所有数据,例如ga("send" ...)在库加载之前。库然后解析这个对象,处理它需要的内容,并将对象清空,但这似乎不是像 Google 的实现一样干净。

4

1 回答 1

3

所以解开缩小的脚本,它看起来像这样(删除了插入脚本标签的代码):

window.GoogleAnalyticsObject = 'ga';

window.ga = window.ga || function(){
    ( window.ga.q = window.ga.q || [] ).push(arguments);
}

window.ga.l = 1 * new Date();

他们创建window.ga并将其分配给将任何参数推入数组的函数,window.ga.q. || 或者操作员在那里确保已经创建的东西不会被覆盖。

因此,当您调用ga('foo', 'bar')它时,只需将这些参数存储在数组中。脚本加载后,它将查找window.ga.q数组并循环遍历其值,找到 'foo' 和 'bar' 并在加载的脚本中调用相应的函数。

于 2014-01-21T10:41:20.530 回答