首页 给文章加上了访问统计
文章
取消

给文章加上了访问统计

关于

一直想实现博客文章访问统计,虽然我这里没几个人看,功能还是要有的吧。

有三种方案:

  1. 谷歌统计
  2. leancloud
  3. 不蒜子

谷歌的方案我这里不再复述了,有兴趣的可以去搜索一下实现方案。

我这里推荐使用leancloud不蒜子

leancloud

  • 优点:支持查看详细访问记录
  • 缺点:需要写部分代码

不蒜子

  • 优点:引入超级简单
  • 缺点:存在网络波动记录不到、无法查看访问详细记录

不蒜子方案

1
2
3
4
5
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
<span id="busuanzi_container_site_uv">本站总访客数<span id="busuanzi_value_site_uv"></span>人</span>
<span id="busuanzi_container_page_pv">本文总阅读量<span id="busuanzi_value_page_pv"></span>次</span>

你没有看错,只需几行全部搞定。

原文

leancloud方案

  1. leancloud注册开发者账号
  2. 新建应用(量不大选用开发版本就行了)
  3. 新建Class ->visited_timesvisitors_record

visited_times: 增加字段post_titlepost_urlvisited_times visitors_record: 增加字段post_urlvisitor_ip

  1. 设置->应用凭证拷贝AppIDAppKey
  2. foot.html添加如下代码(注意替换AppIDAppKey):
    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
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    
    <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
    <script>AV.initialize("AppID", "AppKey");</script>
    <script>
     //新增访问次数
     function addCount(Counter) {
       // 页面(博客文章)中的信息:leancloud_visitors
       // id为page.url, data-flag-title为page.title
       var $visitors = $(".leancloud_visitors");
       var url = $visitors.attr('id').trim();
       var title = $visitors.attr('data-flag-title').trim();
       var query = new AV.Query(Counter);
    
       // 只根据文章的url查询LeanCloud服务器中的数据
       query.equalTo("post_url", url);
       query.find({
         success: function(results) {
           if (results.length > 0) {//说明LeanCloud中已经记录了这篇文章
             var counter = results[0];
             counter.fetchWhenSave(true);
             counter.increment("visited_times");// 将点击次数加1
             counter.save(null, {
               success: function(counter) {
                 var $element = $(document.getElementById(url));
                 var newTimes = counter.get('visited_times');
                 $element.find('.leancloud-visitors-count').text(newTimes);
               },
               error: function(counter, error) {
                 console.log('Failed to save Visitor num, with error message: ' + error.message);
               }
             });
           } else {
             // 执行这里,说明LeanCloud中还没有记录此文章
             var newcounter = new Counter();
             /* Set ACL */
             var acl = new AV.ACL();
             acl.setPublicReadAccess(true);
             acl.setPublicWriteAccess(true);
             newcounter.setACL(acl);
             /* End Set ACL */
             newcounter.set("post_title", title);// 把文章标题
             newcounter.set("post_url", url); // 文章url
             newcounter.set("visited_times", 1); // 初始点击次数:1次
             newcounter.save(null, { // 上传到LeanCloud服务器中
               success: function(newcounter) {
                 var $element = $(document.getElementById(url));
                 var newTimes = newcounter.get('visited_times');
                 $element.find('.leancloud-visitors-count').text(newTimes);
               },
               error: function(newcounter, error) {
                 console.log('Failed to create');
               }
             });
           }
         },
         error: function(error) {
           console.log('Error:' + error.code + " " + error.message);
         }
       });
     }
    
     //仅根据url和title查出当前访问次数,不做+1操作
     function showCount(Counter) {
       var $visitors = $(".leancloud_visitors");
       var url = $visitors.attr('id').trim();
       var title = $visitors.attr('data-flag-title').trim();
       var query = new AV.Query(Counter);
    
       var entries = [];
       $visitors.each(function() {
         entries.push($(this).attr("id").trim());
       });
       query.containedIn('post_url', entries);
       query.find().done(function(results) {
           console.log(results);
           var count_container = '.leancloud-visitors-count';
           for (var i = 0; i < results.length; i++) {
             var item = results[i];
             var url = item.get('post_url');
             var time = item.get('visited_times');
             var element = document.getElementById(url);
             $(element).find(count_container).text(time);
           }
         }).fail(function(object, error) {
           console.log("Error: " + error.code + " " + error.message);
         });
     }
    
     //调用API获取IP
     function getVisitorIpAndJudge() {
       var ip;
       function createCORS(method, url){
         var xhr = new XMLHttpRequest();
         if('withCredentials' in xhr){
           xhr.open(method, url, true);
         }else if(typeof XDomainRequest != 'undefined'){
           var xhr = new XDomainRequest();
           xhr.open(method, url);
         }else{
           xhr = null;
         }
         return xhr;
       }
       var request = createCORS('get', 'https://api.ipify.org/?format=json&callback=?');
       if(request){
         request.onload = function(response){
           console.log(response);
           var obj = JSON.parse(response.currentTarget.response);
           console.log(obj);
           if(obj.ip) {
             ip = obj.ip;
           }else {
             ip = "127.0.0.1";
           }
           judgeVisitor(ip);
         };
         request.send();
       }
     }
    
     //判断访客是否已访问过该文章,及访问时间,符合条件则增加一次访问次数
     function judgeVisitor(ip) {
       var Counter = AV.Object.extend("visited_times");
       var Visitor = AV.Object.extend("visitors_record");
    
       var $postInfo = $(".leancloud_visitors");
       var post_url = $postInfo.attr('id').trim();
    
       var query = new AV.Query(Visitor);
    
       query.equalTo("visitor_ip", ip);
       query.equalTo("post_url", post_url);
       query.find({
         success: function(results) {
           if (results.length > 0) {
             console.log('该IP已访问过该文章');
    
             var oldVisitor = results[0];
    
             var lastTime = oldVisitor.updatedAt;
             var curTime = new Date();
    
             var timePassed = curTime.getTime() - lastTime.getTime();
    
             if(timePassed > 1 * 60 * 1000) {
               console.log('距离该IP上一次访问该文章已超过了1分钟,更新访问记录,并增加访问次数');
    
               addCount(Counter);
    
               oldVisitor.fetchWhenSave(true);
               oldVisitor.save(null, {
                 success: function(oldVisitor) { },
                 error: function(oldVisitor, error) {
                   console.log('Failed to save visitor record, with error message: ' + error.message);
                 }
               });
             } else {
               console.log('这是该IP 1分钟内重复访问该文章,不更新访问记录,不增加访问次数');
               showCount(Counter);
             }
           } else {
             console.log('该IP第一次访问该文章,保存新的访问记录,并增加访问次数');
    
             addCount(Counter);
    
             var newVisitor = new Visitor();
             /* Set ACL */
             var acl = new AV.ACL();
             acl.setPublicReadAccess(true);
             acl.setPublicWriteAccess(true);
             newVisitor.setACL(acl);
             newVisitor.set("visitor_ip", ip);
             newVisitor.set("post_url", post_url);
             newVisitor.save(null, { // 上传到LeanCloud服务器中
               success: function(newVisitor) { },
               error: function(newVisitor, error) {
                 console.log('Failed to create visitor record, with error message: ' + error.message);
               }
             });
           }
         },
         error: function(error) {
           console.log('Error:' + error.code + " " + error.message);
           addCount(Counter);
         }
       });
     }
    
     $(function() {
       if ($('.leancloud_visitors').length == 1) {
         // 文章页面,调用判断方法,对符合条件的访问增加访问次数
         getVisitorIpAndJudge();
       }else if ($('.leancloud_visitors').length > 1){
         console.log("leancloud_visitors>1")
         // 文章列表时
         var Counter = AV.Object.extend("visited_times");
         showCount(Counter)
       }
     });
    </script>
    
  3. 在需要展示的地方增加如下:
    1
    2
    3
    
    <span id="/posts/%E7%BB%99%E6%96%87%E7%AB%A0%E5%8A%A0%E4%B8%8A%E4%BA%86%E8%AE%BF%E9%97%AE%E7%BB%9F%E8%AE%A1/" class="leancloud_visitors" data-flag-title="给文章加上了访问统计">
       <i class="fa fa-eye"><span class="leancloud-visitors-count"></span></i>
    </span>
    

    注:/posts/%E7%BB%99%E6%96%87%E7%AB%A0%E5%8A%A0%E4%B8%8A%E4%BA%86%E8%AE%BF%E9%97%AE%E7%BB%9F%E8%AE%A1/为文章唯一的访问地址,给文章加上了访问统计为文章标题,leancloud-visitors-count值与上一步操作的有关联。

再次部署刷新文章页面去leancloud控制台能看到有访问记录。OK,到此就完成了。

参考文章

本文由作者按照 CC BY 4.0 进行授权

与博客的折腾

加油2022

载入天数...载入时分秒...