单击“使用JavaScript记录日志”

单击“使用JavaScript记录日志”,javascript,jquery,firefox,logging,onclick,Javascript,Jquery,Firefox,Logging,Onclick,我想记录链接上的所有点击 我编写了一个小日志,可以通过url调用它(返回一个空页面)。使用jquery ajax方法调用此url。但不幸的是,如果用户使用firefox(IE中看起来一切正常),并不是每次点击都会被记录下来 我试过很多方法,但都没有办法解决这个问题,有人用胶水吗 HTML代码: <a href="http://google.com" onclick="return loggClick();">Click</a> 编辑:我在示例中遗漏了必须在js调用中传递

我想记录链接上的所有点击

我编写了一个小日志,可以通过url调用它(返回一个空页面)。使用jquery ajax方法调用此url。但不幸的是,如果用户使用firefox(IE中看起来一切正常),并不是每次点击都会被记录下来

我试过很多方法,但都没有办法解决这个问题,有人用胶水吗

HTML代码:

<a href="http://google.com" onclick="return loggClick();">Click</a>

编辑:我在示例中遗漏了必须在js调用中传递动态参数的内容,因此“不可能”删除onclick事件:(

我将开始删除内联的“onclick”代码并稍后绑定事件:

  <a href="http://google.com" rel="outbound" >Click</a>


   $("a[rel=outbound]").click(function(){ 
        var url = this.href; 
        $.ajax({
        async: false,
        type: "POST",
        url: "Logger.ff", //dynamic url to logging action
        data: {
                sid: 'abc123' //random data
                clicked: url
        },
        contentType: "application/x-www-form-urlencoded; charset=UTF-8",
        cache: false
     });
     return true; 
  }); 

$(“a[rel=outbound]”。单击(函数(){
var url=this.href;
$.ajax({
async:false,
类型:“POST”,
url:“Logger.ff”,//记录操作的动态url
数据:{
sid:'abc123'//随机数据
点击:url
},
contentType:“application/x-www-form-urlencoded;charset=UTF-8”,
缓存:false
});
返回true;
}); 
此外,您可能会出现“竞争条件”。在我的示例中,将async设置为false

这将在执行请求之前停止函数返回和跟踪链接

关于异步 我在这里使用
async:false
的原因是,在默认情况下,aync为true,这意味着当浏览器看到
返回:true
并离开页面时,AJAX请求可能只能部分传输

这就是我刚才提到的“竞争条件”。在这里,这是一个廉价的技巧,它通过使浏览器基本上停止,直到请求完成,然后允许浏览器单击链接来避免这种情况

一个更复杂的答案是让它返回“false”(这将杀死浏览器本机的“follow link”行为),然后在
complete
函数中执行真正的重定向

这并不是没有它自己的问题,可能会导致在请求完成时浏览行为缓慢,允许用户有时间单击其他链接,而这些链接似乎什么也不做,然后最终一个请求在随机时间通过,并出现看似随机的重定向

因此,高级解决方案包括阻塞页面的其余部分,并在请求完成时提供某种进度指示


(因此,与
async:false
)相比,在一个简单的示例中,此解决方案的复杂性要难得多)

我认为FF给您带来糟糕结果的原因是您在操作执行之前就离开了页面。正如mhartman的链接所述,如果您在外部链接上使用目标,它应该可以正常工作。如果您不能这样做,那么您可能必须等待日志完成,尽管您可能会看到导航延迟

HTML代码

<a href="http://google.com" onclick="return loggClick(event);">Click</a>

您可能没有想到的第二种服务器端方法是使用一个页面来处理重定向并记录数据

例如:

<a href="LoggerRedirect.ff?url=http://google.com">Click</a>

上面的海报是正确的,它是不可靠的,因为您在页面有机会登录之前就离开了页面

您可以这样做:

1) 返回false,因此href不处于活动状态。 2) 记录单击的时间 3) 使用location.href重定向到本应重定向到的url


如果onclick处理程序需要很长时间才能执行,您可能会看到轻微的延迟。

此示例将在处理链接单击之前触发ajax帖子。我发现我必须同步调用ajax,否则帖子将不会被执行。在这个例子中,我的ajax帖子是在一个PHP页面上附加一个日志文件。此示例非常有效,因为它只将单击事件附加到窗口。它也不会干扰用户单击链接

//attach click event to window
attachClickEvent = function() {
    $(document).on('click', function(e) { //document for IE8 compatibility
        var element = $(e.target);
        var tag = element.prop('tagName');

        if (tag === 'A') {
            var data = {'title':document.title, 'URL':element.attr('href'), 'origin':location.href};
            logData(data);
        }
    });
}

logData = function(data) {
    $.ajax({
        async: false,
        cache: false,
        type: "POST",
        data: data,
        url: 'logger.php',
        success: function(msg) { 
            //debugging
        },
        error: function() {
            //debugging
        }
    });
}

+1我喜欢这样,尽管OP必须控制服务器端代码才能执行位置重定向,对吗?@bendewey什么?你的最后一部分毫无意义。为什么这样更好?onclick有什么问题吗?你认为它能解决问题,还是仅仅因为它更好而建议它?它更好,这里有两个部分的解决方案。但是,让代码“正确”和“工作”始终是一个很好的二对一交易。此外,我也看到了内联方式的奇怪之处,但没有任何意义,因此我通常会像避免瘟疫一样避免它们。谢谢你的回答,在Firefox中工作得很好,但在IE中没有。但是异步:true就足够了。注意,e.preventDefault()与IE8不兼容。我在我的一个网站上实现了类似的功能,问题是很难从点击日志中筛选出“噪音”。我发现蜘蛛点击和人类点击的比例约为50:1。AFAIK大多数爬行器不会为他们访问的每个页面加载JS解释器,所以使用JS记录出站点击似乎足够合理。
<a href="LoggerRedirect.ff?url=http://google.com">Click</a>
//attach click event to window
attachClickEvent = function() {
    $(document).on('click', function(e) { //document for IE8 compatibility
        var element = $(e.target);
        var tag = element.prop('tagName');

        if (tag === 'A') {
            var data = {'title':document.title, 'URL':element.attr('href'), 'origin':location.href};
            logData(data);
        }
    });
}

logData = function(data) {
    $.ajax({
        async: false,
        cache: false,
        type: "POST",
        data: data,
        url: 'logger.php',
        success: function(msg) { 
            //debugging
        },
        error: function() {
            //debugging
        }
    });
}