对于静态博客的一个硬伤就是自身无法实现文章阅读数的统计,必须借助第三方工具。常用的有一键安装使用的卜算子,也有利用 Leancloud 自己存储和显示。
我比较倾向于第二种。毕竟这样可以将自己博客的数据掌握在自己手中,而不是放在别人的服务器,说不定哪天就挂了,就如同多说和网易云跟帖。

这个功能大概一个月前就想添加了,但是迟迟没有动手,没有什么其他原因,就是懒。今天晚上花了点时间完成了基于现在这个主题 [maupassant-hexo] (https://github.com/superman66/maupassant-hexo)的 页面统计和网站 pv 统计。
逻辑很简单,代码就这么几行,具体教程网上找找,一搜一大堆,文件见文末。

接下来就是吐槽时间了。吐槽的对象是 cnzz 数据统计。先说吐槽结论:网站数据统计慎用 cnzz,如果非要用,最后将百度统计和谷歌统计一并加上
利用 LeanCloud 作为统计有个好处就是你可以初始化网站的访问数和每篇文章的阅读数。在今天晚上动手写代码之前,我都已经计划好了,等文章统计阅读数开发好了之后,将 cnzz 统计的页面访问数据和网站总访问量(由于我从博客一开通就使用 cnzz 数据统计,因此 cnzz 的统计数据还算是准确)放到 Leancloud 后台,完成初始化。这样就可以保证数据的准确性了。

所有工作都完成后,当我打开 cnzz 的受访页面分析,选择了过去一年的数据(cnzz 只能选择过去最多395天)想去拿页面访问数据的时候,结果傻眼了:

fuck-cnzz

页面访问数据为空! WTF!数据就这么没了吗?已经打算明天去找客服要个说法去了。太令人伤心了,当初是因为相信 cnzz 才选择它,而放弃了 GA 以及 百度统计。
也给各位开通自己博客的同学们一个建议:一旦打算使用网站数据统计,千万要记得将要有 backup,不能只相信一家之言。要不然,一旦出现数据丢失问题,很有可能这些数据就再也找不回来了。

leadcloud 相关代码如下:
leancloud.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
(function () {
var SITE_VIEWS_TITLE = 'SITE_TITLE';
var HOST = 'chenhuichao.com';
var leancloudService = {
url: window.location.href,
title: $('.post-title').text().trim(),
Counter: null,
init: function () {
AV.init('DicCxG3axqqCc9PCCxf8WAyv-gzGzoHsz', 'yfU0qujWrNIU2tnf3ooNfmgX');
this.Counter = AV.Object.extend('Counter');
if (this.isDetail()) {
this.addDetailCount(this.Counter, this.detailCountSaveCallback);
} else {
this.addExceptDedtailCount(this.Counter, this.siteCountSaveCallback);
}
},
/**
* 获取文章详情访问数
*/
getDetailCount: function (Counter) {
var query = new AV.Query(Counter);
query.equalTo("url", this.url);
return query.find();
},

/**
* 获取 site 访问数
*/
getSiteCount: function (Counter) {
var query = new AV.Query(Counter);
query.equalTo("title", SITE_VIEWS_TITLE);
return query.find();
},

/**
* 增加文章详情页面访问数
*/
addDetailCount: function (Counter, cb) {
// site views increment
this.addExceptDedtailCount(Counter, this.siteCountSaveCallback);

this.getDetailCount(Counter)
.then(function (results) {
if (results.length > 0) {
var counter = results[0];
counter.increment("time");
counter.save({
fetchWhenSave: true,
}).then(cb);
}
else {
var newCounter = new Counter();
newCounter.set('title', title);
newCounter.set('url', url);
newCounter.set('time', 1);
newCounter.save().then(cb, function (error) {
console.error(error);
})
}
})
},
/**
* 统计非详情页的访问,主要是首页、列表页,归档页,关于,category,tag页面
*/
addExceptDedtailCount: function (Counter, cb) {
this.getSiteCount(Counter)
.then(function (results) {
if (results.length > 0) {
var counter = results[0];
counter.increment("time");
counter.save({
fetchWhenSave: true,
}).then(cb);
}
else {
var newCounter = new Counter();
newCounter.set('title', SITE_VIEWS_TITLE);
newCounter.set('url', HOST);
newCounter.set('time', 1);
newCounter.save().then(cb, function (error) {
console.error(error);
})
}
})
},
/**
* 判断是否是文章详情页面
*/
isDetail: function () {
var $title = $('.post-title');
return $title.length == 1 && $title.text();
},

/**
* 详情页保存成功回调
*/
detailCountSaveCallback: function (counter) {
$('#leancloud_value_page_pv').text(counter.attributes.time);
},

siteCountSaveCallback: function (counter) {
$('#site-view').text(counter.attributes.time);
}
};

leancloudService.init();
})()