从服务器向Google Analytics发送文件下载事件

4
非常相关和有用:使用API服务器端发送事件到Google Analytics

通过电子邮件向客户发送下载链接:

您好,
请在此处找到您的产品:https://www.example.com/files/yourfile.zip

我想在Google Analytics中跟踪此下载操作,作为一个 Goal 转换。

不幸的是,当用户单击链接时,该文件会被 直接由Web服务器 提供,而不通过 .html 页面。

如何在Analytics中跟踪这样的直接文件下载?

  1. 我应该添加一个“中间虚拟 HTML 页面”,使用 analytics.js 跟踪代码并使用 ga.send(...) 发送下载事件到GA,然后使用 setTimeout(redirect, 500) 在 500 毫秒后重定向到实际文件吗?这真的是一个干净而安全的解决方案吗?我看到很多潜在的问题:500 ms 是否足够?应该使用什么样的重定向?如果用户禁用了 JS,则永远无法获取文件... 或者如果使用了 <noscript>,则无法记录 Goal 转换。

  2. 是否有一种方法可以要求 Apache(为客户端提供 yourfile.zip 的服务器)或 PHP 在提供此文件时向 Google Analytics 发送跟踪事件?

  3. 其他解决方案?

似乎方案 2. 具有 100% 可靠性的优势,无论客户端是否启用 JS。

但另一方面,我不想使用一个很少使用的 hack。这种非常普遍的情况通常的解决方案是什么?


更准确的副本:https://dev59.com/6VwY5IYBdhLWcg3wyqaH - Basj
1个回答

5
Google Analytics实际上有一个协议,可以从任意来源发送分析数据。请参见此处:https://developers.google.com/analytics/devguides/collection/protocol/v1/ 因此,让您的Web服务器向Google发送分析事件并不像看起来那么hacky。我不确定是否可以直接钩入Apache来生成这些事件。但是,我至少看到了两种解决方案。
1)将所有下载重定向到服务器端脚本,该脚本发送数据并可以生成所需的分析事件。 2)解析服务器日志并从中生成分析事件。
编辑解决方案1的示例: 确保在标签之前和之后没有空格,因为这将成为实际发送给客户端的响应的一部分。
download.php:
<?php
    // Read ?file=xxx URL parameter
    $requestedFile = $_GET["file"];

    // Read Google Analytics cookie
    $rawCookie = $_COOKIE["_ga"];
    $splitCookie = explode('.', $rawCookie);
    $trackingId = $splitCookie[2] . '.' . $splitCookie[3];

    // Create Google Analytics request data (see here https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide)
    $data = array('v' => 1, 
                  'tid' => 'UA-XXXXX-Y', 
                  'cid' => $trackingId, 
                  't' => 'event', 
                  'ec' => 'download', 
                  'ea' => 'download', 
                  'el' => $requestedFile);

    // Create the request options
    $options = array(
        'http' => array(
            'method' => 'POST',
            'content' => http_build_query($data)
        )
    );

    $context = stream_context_create($options);

    // Send GA request
    $result = file_get_contents('https://www.google-analytics.com/collect', false, $context);

    // GA request failed
    if($result === FALSE) { /* Error */ }

    // Requested file does not exist
    if(!file_exists($requestedFile)) { /* Error */ }

    // Set response headers for binary data
    header('Content-Type: application/octet-stream');
    header('Content-Length: ' . filesize($requestedFile));

    // Open the requested file
    $fileHandle = fopen($requestedFile, 'r');

    // Write the requested file to stdout (which is what the client receives)
    print fread($fileHandle, filesize($requestedFile));
    flush();

    // Close the requested file again
    fclose($fileHandle);

    exit;
?>

.htaccess/mod_rewrite规则:

RewriteEngine on
RewriteUrl ^/download/(.*)$ download.php?file=$1 [L]

我已经很久没有写PHP代码了,也没有测试过这个。但是它应该可以很好地说明如何实现选项1)。

编辑2:如果您将跟踪请求发送到www.google-analytics.com/debug/collect,则会收到一些验证信息,告诉您请求是否有效(但不会跟踪事件)。

编辑3: 好的,我已经检查了一个使用analytics.js的页面。该脚本设置了以下cookie:

_ga=GA1.3.1788966449.1501761573
_gid=GA1.3.1010429060.1501761573

在后续的请求中,它设置了

cid:1788966449.1501761573
_gid:1010429060.1501761573

看起来你需要对在_ga cookie中找到的字符串进行一些拆分。(我已经更新了上面的代码)

编辑4: 如果有人想知道,这是analytics.js脚本使用上述cookie值生成的请求。

GET https://www.google-analytics.com/collect?v=1&_v=j56&a=1178408574&t=pageview&_s=1&dl=https%3A%2F%2Fdevelopers.google.com%2Fanalytics%2Fdevguides%2Fcollection%2Fanalyticsjs%2Fcommand-queue-reference&ul=de&de=UTF-8&dt=The%20ga%20Command%20Queue%20Reference%20%C2%A0%7C%C2%A0%20Analytics%20for%20Web%20(analytics.js)%20%C2%A0%7C%C2%A0%20Google%20Developers&sd=24-bit&sr=1920x1200&vp=1899x1072&je=0&_u=QDCAAAIhI~&jid=&gjid=&cid=1788966449.1501761573&tid=UA-41425441-2&_gid=1010429060.1501761573&z=1116872044

Apache提供了mod_rewrite,它允许在服务器上重写URL而不被客户端察觉。因此,您可以将类似/downloads/cool.zip的URL重写为/download.php?file=cool.zip。然后,PHP脚本可以读取文件参数,与Google Analytics进行通信,然后将用户请求的文件发送给他们。 另外,您也可以选择不直接向用户提供下载链接,而是发送/download.php?file=something这样的链接,这样就不需要进行任何服务器端的URL重写。 - Nicolas Ristock
不错的想法@NicolasRistock。但是PHP是否可以访问客户端UUID(存储在客户端cookie中)? PHP需要告诉GoogleAnalytics“客户#3298474已下载文件”,但PHP是否可以访问此UUID? - Basj
据我所知,使用mod_rewrite转发所有请求头(至少有一个选项可以这样做),因为cookie只是客户端发送的一个头部,所以您应该可以从php脚本中访问它们。 - Nicolas Ristock
太好了!您是否可以包含一个小的PHP示例来说明您的解决方案1)? - Basj
1
关于edit3:这意味着在内部,我们放置在页面上的analytics.js片段执行相同的操作:发送一个请求到/collect?v=...。好好知道! - Basj
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接