利用腾讯云无服务器函数加速Google Analytics

最近重新开始打理博客后,看到自己的ga统计都被自己浏览器插件过滤了icon_question.gif重新给处理一下吧

首先是看了的 BFDZ 大佬的 Google Analytics 加载优化 然后用了两天,觉得还不错,准备自己建一个,但是又不想大张旗鼓的部署在服务器上面 主要是因为穷,没钱

然后看到腾讯云的无服务器函数正在测试,然后据说以后还是有免费额度的,蹭一蹭

无服务器云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。SCF 是实时文件处理和数据处理等场景下理想的计算平台。


先创建一个PHP的函数

(为什么?因为PHP是世界上最好的语言)

1.png

2.png

直接在线编辑函数代码

修改执行方法为index.ga
然后在代码框填入以下代码

<?php
function ga($event, $context){

    //拦截参数不完整
    if(!isset($event->headers->referer) || 
        !isset($event->headers->{'user-agent'}) || 
        !isset($event->queryString->ga) || 
        !isset($event->queryString->dt) || 
        !isset($event->queryString->dr) ||  
        !isset($event->queryString->ul) ||  
        !isset($event->queryString->sd) ||  
        !isset($event->queryString->sr) ||  
        !isset($event->queryString->vp) || 
        !isset($event->queryString->z))
    {
        $ret = array(
            'statusCode'=>403,
            'headers'=>array("content-type"=>"text/html"),
            'body'=>'403',
            'isBase64'=>false
            );
        return $ret;
    }

    //处理cookies
    if(isset($event->headers->cookie)){
        $cookies = $event->headers->cookie;
        if(stripos($cookies,';')===false){
            //本域名下cookie应该只存在uuid一个值
            $array_uuid = explode('=',$cookies);
            if(count($array_uuid)==2 && $array_uuid[0]=='uuid')$uuid = $array_uuid[1];
        }else{
            //cookie被提交了多个值,分割值
            $array_cookie = explode(';',$cookies);
            foreach ($array_cookie as $value){
                $array_uuid = explode('=',$value);
                if(count($array_uuid)==2 && $array_uuid[0]=='uuid'){
                    $uuid = $array_uuid[1];
                    break;//取第一个uuid
                }
            }
        }
    }

    if (!isset($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);
    }

    $url='v=1&t=pageview&';
    $url.='tid='.$event->queryString->ga.'&';
    $url.='cid='.$uuid.'&';
    $url.='dl='.rawurlencode(rawurldecode($event->headers->referer)).'&';
    $url.='uip='.rawurlencode(rawurldecode($event->requestContext->sourceIp)).'&';
    $url.='ua='.rawurlencode(rawurldecode($event->headers->{'user-agent'})).'&';
    $url.='dt='.rawurlencode(rawurldecode($event->queryString->dt)).'&';
    $url.='dr='.rawurlencode(rawurldecode($event->queryString->dr)).'&';
    $url.='ul='.rawurlencode(rawurldecode($event->queryString->ul)).'&';
    $url.='sd='.rawurlencode(rawurldecode($event->queryString->sd)).'&';
    $url.='sr='.rawurlencode(rawurldecode($event->queryString->sr)).'&';
    $url.='vp='.rawurlencode(rawurldecode($event->queryString->vp)).'&';
    $url.='z='.$event->queryString->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);

    $extime = date(DATE_COOKIE,time()+368400000);
    $ret = array(
        'statusCode'=>204,
        'headers'=>array(
            "content-type"=>"image/jpg",
            "set-cookie"=>"uuid={$uuid}; expires={$extime}; path=/; HttpOnly"
            ),
        'body'=>'is work',
        'isBase64'=>false
        );
    return $ret;
}
?>

可以保存测试一下,应该会输出403,因为没有附带参数被拦截了

触发方式

添加一个触发方式,选择API网关触发
3.png

启用响应集成

默认添加API网关后已经可以访问了,但是会输出json,为了世界的和平,我们要自定义响应头为204加快一下浏览器的处理速度
进入API网关编辑一下刚才新建的网关
4.png

5.png

除了后端这里打钩,其他都默认不用改(貌似进这个页面默认是打钩的),然后提交

提交后记得要发布

6.png

绑定自定义域名

7.png

可以绑定自定义域名并且支持SSL,当然备案是必须的~

前端应用

在合适的地方插入以下JS代码即可

    <script>
    function ga(a, b, c, d, e) {
    var f = c.screen,
        g = encodeURIComponent,
        h = ["ga=" + a, "dt=" + g(d.title), "dr=" + g(d.referrer), "ul=" + (e.language || e.browserLanguage || e.userLanguage), "sd=" + f.colorDepth + "-bit", "sr=" + f.width + "x" + f.height, "vp=" + Math.max(d.documentElement.clientWidth, c.innerWidth || 0) + "x" + Math.max(d.documentElement.clientHeight, c.innerHeight || 0), "z=" + +new Date];
        c.__ga_img = new Image, c.__ga_img.src = b + "?" + h.join("&")
    }
    ga("UA-XXXXXX-1", "https://ga.cuojue.org/ga/ga/", window, document, navigator, location);
    </script>

为什么我要把函数封装以下独立出来呢,因为现在博客用的模板是pjax加载的,所以要在pjax加载完毕后回调一下这个函数,让每个页面都统计到

继续改进

现在函数是同步返回的,有空看下改成异步执行加快一下速度~


参考内容:
https://www.bfdz.ink/2018/10/23/109/

https://stneng.com/google-analytics-%E5%BC%82%E6%AD%A5%E8%AF%B7%E6%B1%82%EF%BC%88%E6%9C%8D%E5%8A%A1%E7%AB%AF%E8%AF%B7%E6%B1%82%EF%BC%89/

https://imququ.com/post/summary-of-my-blog-optimization.html#toc-2

Last modification:November 19th, 2018 at 01:37 am

4 comments

  1. 小样

    厉害,真爱折腾...

    1. WeiCN
      @小样

      继续折腾了一下,写了个tp插件 适用于Typecho的Google Analytics加速插件

  2. BFDZ

    我那篇是转载的,你是真大佬

    1. WeiCN
      @BFDZ

      现在虽然实现了功能,但是是同步返回的,速度都300ms以上了,还是要改进成异步的,争取进入100ms俱乐部

Leave a Comment