将Google Analytics移到服务端

Google Analytics

Google Analytics

前言

一般地,网站配置 Google An­a­lyt­ics 的常见方式是在网站前端引用 Google Analytics 的 trackercode,然后获取 analytics.js 并开始统计用户行为。由于国内访问Google不顺畅,这种方式使用Google  Analytics造成国内的访问缓慢。虽然通过使用大公司的 ga.js 的 CDN ,可以很大程度上加快加载 ga.js 文件的速度( ga.js 的更新频率很高,并不适合缓存到本地或服务器)。但无论如何还是要向 Google 发送一个请求来发送访客数据,所以取巧地使用 CDN 并不能从根本上解决问题。

在 JerryQu 的 《本博客零散优化点汇总》 一文中提到他是如何处理 Google Analytics 的:

把统计逻辑挪到了服务端;自己生成用户唯一标识,获取访问页面的标题、URL、Referer,获取用户 IP 和浏览器 UA,随着每次访问发给 Google 的统计地址。服务端向 Google 发起的请求是异步的,用户端访问速度丝毫不受影响。

Google Analytics 的 官方文档 给出了相关介绍,Google 也提供了 Measurement Protocol

Google Analytics 异步方案

目前常见的是这两种方法:完整的后端方案和前端和后端搭配的方案。

前者通过配置 Nginx,使用 uid 模块和 proxy_pass 向后端转发请求;后者的方案则是通过 JS 发送请求给中转服务,再由中转服务器异步发送给 Google。对于前者的解决方案的实现可以阅读下述文章:

还有一种方案,就是在前端通过 JS 发起一个请求、生成用户端的信息带到请求的 URI 上,然后后端的有关程序监听这个请求,并异步发送给 Google。

对于这种解决方案,有人写了一个 Node.js(基于 ThinkJS) 的程序实现:《服务端使用 Google Analytics》

PHP异步方案

我想,没有 Node.js 支持的虚拟主机,又不是所有人都有独立的 VPS 的,也不是所有人都使用 Node.js 的。所以我根据这种思路,找到了个 PHP 版的。


<?php
// ********************
// * Author: stneng
// * Date: 2016.12.11
// * Introduction: https://u.nu/ytq
// *********************
    header("status: 204");
    header("Cache-Control: no-cache, max-age=0");
    header("Pragma: no-cache");

    $tid='';  // 在这里写 Google Analytics 给的 tid,形如:UA-XXXX-Y

    function create_uuid(){$str = md5(uniqid(mt_rand(), true));
        $uuid = substr($str,0,8) . '-';
        $uuid .= substr($str,8,4) . '-';
        $uuid .= substr($str,12,4) . '-';
        $uuid .= substr($str,16,4) . '-';
        $uuid .= substr($str,20,12);
        return $uuid;
    }

    if (!isset($_COOKIE["uuid"])) {$uuid=create_uuid();
        setcookie("uuid", $uuid , time()+368400000);
    }else{$uuid=$_COOKIE["uuid"];
    }

    if (function_exists("fastcgi_finish_request")) {fastcgi_finish_request(); // 对于 fastcgi 会提前返回请求结果,提高响应速度。
    }

    $url='v=1&t=pageview&';
    $url.='tid='.$tid.'&';
    $url.='cid='.$uuid.'&';
    $url.='dl='.rawurlencode(rawurldecode($_SERVER['HTTP_REFERER'])).'&';
    $url.='uip='.rawurlencode(rawurldecode($_SERVER['REMOTE_ADDR'])).'&';
    $url.='ua='.rawurlencode(rawurldecode($_SERVER['HTTP_USER_AGENT'])).'&';
    $url.='dt='.rawurlencode(rawurldecode($_GET['dt'])).'&';
    $url.='dr='.rawurlencode(rawurldecode($_GET['dr'])).'&';
    $url.='ul='.rawurlencode(rawurldecode($_GET['ul'])).'&';
    $url.='sd='.rawurlencode(rawurldecode($_GET['sd'])).'&';
    $url.='sr='.rawurlencode(rawurldecode($_GET['sr'])).'&';
    $url.='vp='.rawurlencode(rawurldecode($_GET['vp'])).'&';
    $url.='z='.$_GET['z'];
    $url='https://www.google-analytics.com/collect?'.$url;
    $ch=curl_init();
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_exec($ch);
      curl_close($ch);

?>

将上述代码保存为 google.php,放在网站根目录。

当然你也可以命名为其它的,不过你需要修改下述提到的 script。

在页面中插入下述代码:

<script>!function(e,n,o){var t=e.screen,a=encodeURIComponent,r=["dt="+a(n.title),"dr="+a(n.referrer),"ul="+(o.language||o.browserLanguage),"sd="+t.colorDepth+"-bit","sr="+t.width+"x"+t.height,"vp="+e.innerWidth+"x"+e.innerHeight,"z="+ +new Date],i="?"+r.join("&");e.__beacon_img=new Image,e.__beacon_img.src="/google.php"+i}(window,document,navigator,location);</script>

上面这段代码是直接修改自 imququ.com 的 ana_js如下:


(function(window, document, navigator, location) {
var screen = window.screen;
var encode = encodeURIComponent;

var data = ['dt=' + encode(document.title),
'dr=' + encode(document.referrer),
'ul=' + (navigator.language || navigator.browserLanguage),
'sd=' + screen.colorDepth + '-bit',
'sr=' + screen.width + 'x' + screen.height,
'_=' + (+new Date)
];

var query = '?' + data.join('&amp;');

window.__beacon_img = new Image();
window.__beacon_img.src = '/ga.php' + query;
})(window, document, navigator, location);

这段 JS 代码完成了 URI 生成和发起请求两个操作。

后端 PHP 程序包含了 uuid 生成、cookie 校验和转发请求三个部分。

首先是用 md5 生成符合 Google Analytics 的唯一用户 uid,作为辨别不同用户的依据。
然后会从客户端的 cookie 来进行匹配,判断是否是回访的访客。如果客户端没有相关 cookie,这个请求就会把 uuid 写进用户端的 cookie 中。
然后就是解析 URI,通过请求采集请求的 URI 获取有关信息,然后组成 www.google-analytics.com/collect 适用的 URI。
最后就是服务端通过发起 cURL 请求 www.google-analytics.com,把统计的页面行为提交给 Google 即可。

转载修改自:Google Analytics 异步化方案

评论

《 “将Google Analytics移到服务端” 》 有 9 条评论

  1. zhujiwiki 的头像

    在用gg统计,暂时没感觉到速度的影响。
    这个方法,有空试下

  2. Nchyn 的头像
    Nchyn

    给出的js中…
    src=”/ga.php”

    1. gemcjz 的头像
      gemcjz

      感谢!已更正。

  3. 夏日博客 的头像

    现在的 Node.js 很火呀。

  4. 新闻头条 的头像

    文章不错非常喜欢

  5. 夏日博客 的头像

    现在基本上都不敢调用GG的资源了,加载不了。

  6. 知道91博客 的头像

    要翻墙吧,不然永不了吧

    1. gemcjz 的头像
      gemcjz

      服务器在墙外就可以了。

  7. 新闻头条 的头像

    文章不错非常喜欢

回复 gemcjz 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理