竞争条件和同步使用 Google Analytics 异步 (_gaq)

发布于 2024-09-13 09:51:46 字数 691 浏览 5 评论 0原文

我有一个网站正在使用 Google Analytics 较新的异步跟踪方法 (_gaq)。我遇到的问题是我想建立一些特定的链接跟踪,并且担心我会创建竞争条件。

基本上,它是一个新闻网站,因此它的标题链接到各地的故事。一个故事的标题可能会出现在一个页面上的 3 个不同位置,并出现在数百个其他页面上。因此,为了了解我们的受众如何与网站互动,我们必须跟踪每个特定标题块的使用方式,而不仅仅是目的地。由于跟踪单个页面的这两个规定,仅跟踪引用的页面是不够的,我们必须跟踪单个链接。

所以如果我有一个链接。

<a href="http://www.blah.com" onclick="_gaq.push('_trackEvent','stuff')">Here</a>

由于 _gaq.push() 是异步调用,那么页面更改是否有可能在 Google 完成点击跟踪之前发生?如果是这样,有没有办法防止这种情况,或者我对 Google Analytics 异步功能的方式有误解(http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html)。

I have a website which is using Google Analytics newer asynchronous tracking method (_gaq). The problem I've run into is that I want to institute some specific link tracking and am worried that I will be creating a race condition.

Basically, it's a news website so it has headlines which link to stories all over the place. A headline for a story might appear in 3 different places on a page, and appear on hundreds of other pages. Thus, in order to understand how our audience is interacting with the site we have to track how each specific headline block is used, and not just the destination. Because of those two stipulations tracking individual pages, nor tracking referred pages won't be enough, we have to track individual links.

So if I have a link.

<a href="http://www.blah.com" onclick="_gaq.push('_trackEvent','stuff')">Here</a>

Because _gaq.push() is an asynchronous call, isn't it possible that the page change will occur prior to Google's completion of the click tracking? If so is there a way to prevent that, or do I have a misunderstanding about the way that Google Analytics Async functions (http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

段念尘 2024-09-20 09:51:46

你说得对。如果浏览器在发送事件的 GA 跟踪信标(gif hit)之前离开页面,则不会记录该事件。然而,这对于异步代码来说并不新鲜,因为发送跟踪信标的过程是异步的;旧代码在这方面的工作方式相同。如果跟踪确实那么重要,您可以执行以下操作:

function track(link) {
  if (!_gat) return true;
  _gaq.push(['_trackEvent', 'stuff']);
  setTimeout(function() {location.href=link.href'}, 200);
  return false;
}

...

<a href="example.com" onclick="return track(this);"></a>

如果 GA 已加载,则单击链接时将阻止浏览器转到下一页(最好不要让用户等待那么长时间)。然后,它发送事件并等待 200 毫秒,将用户发送到他们单击的链接的 href。这增加了事件被记录的可能性。您可以通过延长超时时间来进一步增加可能性,但这也可能会损害此过程中的用户体验。这是一个你必须尝试的平衡。

You're right. If the browser leaves the page before it sends the GA tracking beacon (gif hit) for the event, the event will not be recorded. This is not new to the async code however, because the process of sending the tracking beacon is asynchronous; the old code worked the same way in that respect. If tracking is really that important, you could do something like this:

function track(link) {
  if (!_gat) return true;
  _gaq.push(['_trackEvent', 'stuff']);
  setTimeout(function() {location.href=link.href'}, 200);
  return false;
}

...

<a href="example.com" onclick="return track(this);"></a>

This will stop the browser from going to the next page when the link is clicked if GA has been loaded already (it's probably best to not make the user wait that long). Then it sends the event and waits 200 milliseconds to send the user to the href of the link they clicked on. This increases the likelihood that the event will be recorded. You can increase the likelihood even more by making the timeout longer, but that also may be hurting user-experience in the process. It's a balance you'll have to experiment with.

2024-09-20 09:51:46

我也遇到了这个问题,并且决心找到一个真正的解决方案。

将函数推入队列怎么样?

  // Log a pageview to GA for a conversion
  _gaq.push(['_trackPageview', url]);
  // Push the redirect to make sure it happens AFTER we track the pageview
  _gaq.push(function() { document.location = url; });

I've got this problem too, and am determined to find a real solution.

What about pushing the function into the queue?

  // Log a pageview to GA for a conversion
  _gaq.push(['_trackPageview', url]);
  // Push the redirect to make sure it happens AFTER we track the pageview
  _gaq.push(function() { document.location = url; });
心安伴我暖 2024-09-20 09:51:46

来自 Google 通用分析文档(新版本因为这个问题的大多数其他答案)。您现在可以轻松指定回调。

var trackOutboundLink = function(url) {
   ga('send', 'event', 'outbound', 'click', url, {'hitCallback':
     function () {
     document.location = url;
     }
   });
}

为了清楚起见,我建议使用此语法,这样可以更清楚地显示您要发送的属性并更轻松地添加更多属性:

            ga('send', 'event', {
                'eventCategory': 'Homepage',
                'eventAction': 'Video Play',
                'eventLabel': label,
                'eventValue': null,

                'hitCallback': function()
                {
                    // redirect here
                },

                'transport': 'beacon',

                'nonInteraction': (interactive || true ? 0 : 1)
            });

[这里有一个 所有可能的 ga 调用的完整参数列表。]

此外,我还添加了 transport 参数设置为 beacon (实际上不需要,因为它会在适当的情况下自动设置):

这指定了发送点击的传输机制。
选项为“beacon”、“xhr”或“image”。默认情况下,analytics.js
将尝试根据命中大小找出最佳方法
浏览器功能。如果您指定“beacon”和用户的浏览器
不支持navigator.sendBeacon方法,会回退
为“image”或“xhr”,具体取决于命中大小。

因此,当使用 navigator.beacon 导航不会中断跟踪。不幸的是,微软对信标的支持不存在,因此您仍然应该将重定向放在回调中。

From Google's documentation for universal analytics (new version since most other answers for this question). You can now easily specify a callback.

var trackOutboundLink = function(url) {
   ga('send', 'event', 'outbound', 'click', url, {'hitCallback':
     function () {
     document.location = url;
     }
   });
}

For clarity I'd recommend using this syntax, which makes it clearer which properties you're sending and easier to add more :

            ga('send', 'event', {
                'eventCategory': 'Homepage',
                'eventAction': 'Video Play',
                'eventLabel': label,
                'eventValue': null,

                'hitCallback': function()
                {
                    // redirect here
                },

                'transport': 'beacon',

                'nonInteraction': (interactive || true ? 0 : 1)
            });

[Here's a complete list of parameters for all possible ga calls.]

In addition I've added the transport parameter set to beacon (not actually needed because it's automatically set if appropriate):

This specifies the transport mechanism with which hits will be sent.
The options are 'beacon', 'xhr', or 'image'. By default, analytics.js
will try to figure out the best method based on the hit size and
browser capabilities. If you specify 'beacon' and the user's browser
does not support the navigator.sendBeacon method, it will fall back
to 'image' or 'xhr' depending on hit size.

So when using navigator.beacon the navigation won't interrupt the tracking . Unfortunately Microsoft's support for beacon is non existent so you should still put the redirect in a callback.

迷爱 2024-09-20 09:51:46

在事件处理程序中,您应该设置点击回调:

_gaq.push(['_set', 'hitCallback', function(){
  document.location = ...
}]);

向您发送数据

_gaq.push(['_trackEvent'

并停止事件事件处理

e.preventDefault();
e.stopPropagation();

In event handler you should setup hit callback:

_gaq.push(['_set', 'hitCallback', function(){
  document.location = ...
}]);

send you data

_gaq.push(['_trackEvent'

and stop event event processing

e.preventDefault();
e.stopPropagation();
素罗衫 2024-09-20 09:51:46

我正在尝试一种新方法,我们自己构建 utm.gif 的 URL,并请求它,然后只有在收到响应(gif)后,我们才会向用户发送:

用法:

  trackPageview(url, function() { document.location = url; });

代码(来自 CrumbleCookie :http://www.dannytalk.com/read-google-analytics-cookie -脚本/)

/** 
 * Use this to log a pageview to google and make sure it gets through
 * See: http://www.google.com/support/forum/p/Google%20Analytics/thread?tid=5f11a529100f1d47&hl=en 
 */
function trackPageview(url, fn) {
  var utmaCookie = crumbleCookie('__utma');
  var utmzCookie = crumbleCookie('__utmz');

  var cookies = '__utma=' + utmaCookie + ';__utmz=' + utmzCookie;

  var requestId = '' + (Math.floor((9999999999-999999999)*Math.random()) + 1000000000);
  var hId = '' + (Math.floor((9999999999-999999999)*Math.random()) + 1000000000);

  var utmUrl = 'http://www.google-analytics.com/__utm.gif';
  utmUrl += '?utmwv=4.8.9';
  utmUrl += '&utmn=' + requestId;
  utmUrl += '&utmhn=' + encodeURIComponent(window.location.hostname);
  utmUrl += '&utmhid=' + hId;
  utmUrl += '&utmr=-';
  utmUrl += '&utmp=' + encodeURIComponent(url);
  utmUrl += '&utmac=' + encodeURIComponent(_gaProfileId); 
  utmUrl += '&utmcc=' + encodeURIComponent(cookies);

  var image = new Image();
  image.onload = function() { fn(); };
  image.src = utmUrl;
}

/**
 *  @author:    Danny Ng (http://www.dannytalk.com/read-google-analytics-cookie-script/)
 *  @modified:  19/08/10
 *  @notes:     Free to use and distribute without altering this comment. Would appreciate a link back :)
 */

// Strip leading and trailing white-space
String.prototype.trim = function() { return this.replace(/^\s*|\s*$/g, ''); }

// Check if string is empty
String.prototype.empty = function() {
    if (this.length == 0)
        return true;
    else if (this.length > 0)
        return /^\s*$/.test(this);
}

// Breaks cookie into an object of keypair cookie values
function crumbleCookie(c)
{
    var cookie_array = document.cookie.split(';');
    var keyvaluepair = {};
    for (var cookie = 0; cookie < cookie_array.length; cookie++)
        {
        var key = cookie_array[cookie].substring(0, cookie_array[cookie].indexOf('=')).trim();
        var value = cookie_array[cookie].substring(cookie_array[cookie].indexOf('=')+1, cookie_array[cookie].length).trim();
        keyvaluepair[key] = value;
    }

    if (c)
        return keyvaluepair[c] ? keyvaluepair[c] : null;

    return keyvaluepair;
}

I'm trying out a new approach where we build the URL for utm.gif ourselves, and request it, then only once we've received the response (the gif) we send the user on their way:

Usage:

  trackPageview(url, function() { document.location = url; });

Code (CrumbleCookie from: http://www.dannytalk.com/read-google-analytics-cookie-script/)

/** 
 * Use this to log a pageview to google and make sure it gets through
 * See: http://www.google.com/support/forum/p/Google%20Analytics/thread?tid=5f11a529100f1d47&hl=en 
 */
function trackPageview(url, fn) {
  var utmaCookie = crumbleCookie('__utma');
  var utmzCookie = crumbleCookie('__utmz');

  var cookies = '__utma=' + utmaCookie + ';__utmz=' + utmzCookie;

  var requestId = '' + (Math.floor((9999999999-999999999)*Math.random()) + 1000000000);
  var hId = '' + (Math.floor((9999999999-999999999)*Math.random()) + 1000000000);

  var utmUrl = 'http://www.google-analytics.com/__utm.gif';
  utmUrl += '?utmwv=4.8.9';
  utmUrl += '&utmn=' + requestId;
  utmUrl += '&utmhn=' + encodeURIComponent(window.location.hostname);
  utmUrl += '&utmhid=' + hId;
  utmUrl += '&utmr=-';
  utmUrl += '&utmp=' + encodeURIComponent(url);
  utmUrl += '&utmac=' + encodeURIComponent(_gaProfileId); 
  utmUrl += '&utmcc=' + encodeURIComponent(cookies);

  var image = new Image();
  image.onload = function() { fn(); };
  image.src = utmUrl;
}

/**
 *  @author:    Danny Ng (http://www.dannytalk.com/read-google-analytics-cookie-script/)
 *  @modified:  19/08/10
 *  @notes:     Free to use and distribute without altering this comment. Would appreciate a link back :)
 */

// Strip leading and trailing white-space
String.prototype.trim = function() { return this.replace(/^\s*|\s*$/g, ''); }

// Check if string is empty
String.prototype.empty = function() {
    if (this.length == 0)
        return true;
    else if (this.length > 0)
        return /^\s*$/.test(this);
}

// Breaks cookie into an object of keypair cookie values
function crumbleCookie(c)
{
    var cookie_array = document.cookie.split(';');
    var keyvaluepair = {};
    for (var cookie = 0; cookie < cookie_array.length; cookie++)
        {
        var key = cookie_array[cookie].substring(0, cookie_array[cookie].indexOf('=')).trim();
        var value = cookie_array[cookie].substring(cookie_array[cookie].indexOf('=')+1, cookie_array[cookie].length).trim();
        keyvaluepair[key] = value;
    }

    if (c)
        return keyvaluepair[c] ? keyvaluepair[c] : null;

    return keyvaluepair;
}
日裸衫吸 2024-09-20 09:51:46

使用 onmousedown 而不是 onclick 也可能有帮助。它并没有消除竞争条件,但它让 GA 领先一步。还有人担心有人点击链接并在松开鼠标按钮之前将其拖走,但这可能是一个可以忽略不计的情况。

Using onmousedown instead of onclick may also help. It doesn't eliminate the race condition, but it gives GA a head start. There's also the concern of someone clicking on a link and dragging away before letting go of the mouse button, but that's probably a negligible case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文