目录
统计进行的背景
统计的构思
统计的代码实现
更新于2018年9月1日:本文的获取Mac 地址放到服务器测试获取不到访问者的MAC,UV 最后使用还是访问的 IP 数。希望有可以获取到访问者Mac地址的小伙伴不吝赐教。
JS 代码实现,统计页面访问时长,及是否跳出
var current = Date.parse(new Date())/1000;
var url = self.location.href; // 获取用户当前访问页面
var out_num;
var page_view_long = 0;
var endMytime = current+30*60; // 计算过期时间戳
window.onload = function () {
//$.cookie('statistics',null);
out_num = $.cookie('statistics');
if (isNaN(out_num)||out_num==null){
console.log('if');
out_num = $.cookie("statistics",0,{expires:endMytime});
}else{
// $.cookie("statistics",out_num);
out_num++;
console.log('else',out_num);
$.cookie("statistics",out_num,{expires:endMytime});
}
}();
window.addEventListener('beforeunload', logData, false);
function logData() {
var end = Date.parse(new Date())/1000;
out_num = $.cookie('statistics');
page_view_long = end-current;
if (out_num>=1){
out = 0
}else{
out = 1;
}
$.cookie("statistics",out_num);
// window.navigator.sendBeacon("/statistics", 'id=xxx&s=2&_token='+csrf_token);
var client = new XMLHttpRequest();
client.open("POST", "/statistics", false); // 第三个参数表明是同步的 xhr
client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
client.send('url='+url+'&_token='+csrf_token+'&out='+out+'&page_view_long='+page_view_long+'¤t='+current+'&out_num='+out_num);
}
中间件 记录了所有请求的记录。js 的记录不包括AJAX 和 FORM 表单提交。具体要存储的信息在中间件存入redis 队列即可。
代码根据自己的需求写,如些列举一些常用函数。
'data',
...
];
Redis::lpush('WebStatistics', json_encode($redisLine, JSON_UNESCAPED_UNICODE));
return $next($request);
}else{
return $next($request);
}
}
/**
* Handle an incoming request ip addr.
*
* @TODO 获取用户IP地址
* @param string|null
* @return string
* */
private function getIp()
{
if(!empty($_SERVER["HTTP_CLIENT_IP"]))
{
$cip = $_SERVER["HTTP_CLIENT_IP"];
}
else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
{
$cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
else if(!empty($_SERVER["REMOTE_ADDR"]))
{
$cip = $_SERVER["REMOTE_ADDR"];
}
else
{
$cip = '';
}
preg_match("/[\d\.]{7,15}/", $cip, $cips);
$cip = isset($cips[0]) ? $cips[0] : 'unknown';
unset($cips);
return $cip;
}
/**
* @TODO 获得访问者浏览器
* @return string
*/
private function browseInfo() {
if (!empty($_SERVER['HTTP_USER_AGENT'])) {
$br = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('/MSIE/i', $br)) {
$br = 'MSIE';
} else if (preg_match('/Firefox/i', $br)) {
$br = 'Firefox';
} else if (preg_match('/Chrome/i', $br)) {
$br = 'Chrome';
} else if (preg_match('/Safari/i', $br)) {
$br = 'Safari';
} else if (preg_match('/Opera/i', $br)) {
$br = 'Opera';
} else {
$br = 'Other';
}
return $br;
} else {
return 'unknow';
}
}
function GetMacAddr($os_type){
switch ( strtolower($os_type) ){
case "linux":
self::forLinux();
break;
case "solaris":
break;
case "unix":
break;
case "aix":
break;
default:
self::forWindows();
break;
}
$temp_array = array();
foreach ( $this->return_array as $value ){
if (
preg_match("/[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f]/i",$value,
$temp_array ) ){
$this->mac_addr = $temp_array[0];
break;
}
}
unset($temp_array);
return $this->mac_addr;
}
function forWindows(){
@exec("ipconfig /all", $this->return_array);
if ( $this->return_array )
return $this->return_array;
else{
$ipconfig = $_SERVER["WINDIR"]."\system32\ipconfig.exe";
if ( is_file($ipconfig) )
@exec($ipconfig." /all", $this->return_array);
else
@exec($_SERVER["WINDIR"]."\system\ipconfig.exe /all", $this->return_array);
return $this->return_array;
}
}
function forLinux(){
@exec("ifconfig -a", $this->return_array);
return $this->return_array;
}
}
定时任务 ,根据存储的 Redis,进行出队。Redis 无回滚功能。如果出队的数据不符合存储条件可继续入队。不会影响本次出队的循环。Redis 出队循环示例:
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$current = time();
$count = Redis::LLEN('WebStatistics');
$redisList = Redis::lrange('WebStatistics',0,$count);
// dd($redisList);
// TODO 埋点统计 访问页面的信息,每小时即出队清空一次 redis 数据 WebStatistics 。
array_walk($redisList,function($value,$key){
// 每次循环初始化
$lpop = '';$create=false;$saveParams=[];
$lpop = Redis::rpop('WebStatistics');
$saveParams = json_decode($lpop,1);
});
}
前端全(无)埋点之页面停留时长统计
关于页面停留时间
【百度统计】“跳出率”是如何统计的?为什么我的网站跳出率这么高?
独立访客数UV、访问量PV和IP数的区别
js记录用户在网站的浏览记录和停留时间