CDN后用Ajax动态提交、显示文章阅读量,cookies避免重复刷新
编辑:狂族晨曦 来源:WordPress技巧 日期:2017-08-29 阅读: 7,147 次 16 条评论 » 百度已收录
上篇文章解决了WordPress加入CDN后“非插件浏览次数统计”浏览次数不刷新问题,同时留下了两个未解决的问题:
1.按F5可无限制刷新文章访问量,并影响数据库效率;2.只解决了后台不更新问题,前台显示还是得等CDN刷新后才能更新。
那么这篇文章就是为了解决以上两个问题。
问题分析
第一个问题,先森想到的解决方法是用JS代码创建cookies,如果cookies存在就不在更新后台的统计量。
第二个问题,直接让ajax获取后台的访问量,修改前台显示的访问量就行了。
一开始,先森配置的让ajax多传一个参数,是判断cookies是否存在的,存在为1,不存在为0。
若cookies不存在,则后台访问量统计就+1,并返回数据库中的浏览量并+1。
若cookies存在,则后台不增加访问数量,直接返回数据库中的浏览量并+1,如此访客刷新也不会增加访问量了。
但是这样还是存在会在后台查询数据的问题,查询多了对数据库也是一种负担。
先森之前没有意识到这个问题,结果还是晚上睡觉前反思发现了,且也琢磨除了一个更好的解决方法。
直接在JavaScript代码中加判断,如果cookies已存在,则直接不向后端服务器发数据。这样一来,前端再怎么刷新,也停留在CDN的层面上。
那么要实现这种效果,就需要先实现不向后端服务器发送数据,也能获取到当前文章的访问量。解决方法很简单,第一次获取访问量时,将后端服务器返回的访问量直接写入cookies,下次刷新时,直接从cookies中读取访问量。
另外,还有一个地方需要解释一下,cookies的过期时间。如果cookies时间太长了的话,那么未免还是会损失一些访问量,所以先森就没有设置cookies的过期时间,保持默认。cookies的默认过期为关闭浏览器,先森觉得,这样一来还是比较合理的。
同时,一个访客,可能并不会只打开本站一篇文章就关闭,打开多篇文章时,每篇文章的访问量是不一样的,需要从cookies中获取的话,cookies的名称就必须不一样。不然访问打开其他文章,看到了访问量都是同一个数值。解决方法就是,已“固定值+文章ID”的方式,确定cookies名称的唯一。
效果实现
上一篇文章中,先森是模仿通用的评论ajax提交的处理方式,自建了一个类似的php。但这样可能有点不安全,也有点麻烦,所以先森还是研究着将php代码部分放进了主题的functions.php。
首先还是在footer.php中添加ajax的代码,注意需要将前台显示访问量的标签ID或class名称改成自己的。
<script type= "text/javascript" > function GetCookie(sName) { var arr = document.cookie.match(new RegExp("(^| )"+sName+"=([^;]*)(;|$)")); if(arr !=null){return unescape(arr[2])}; return null; } var postviews_cook=GetCookie("postviews<?php the_ID();?>"); if ( postviews_cook == null ){ $.ajax({ type:'POST', url: "<?php echo admin_url('admin-ajax.php');?>" , data:"postviews_id=<?php the_ID();?>&action=postviews", cache:false,success: function(postviews_count){ $("#views").text('阅读:' + postviews_count + ' 次');document.cookie="postviews<?php the_ID();?>=" + postviews_count;} }); } else{ $("#views").text('阅读:' + postviews_cook + ' 次'); }; </script> <?php endif ; ?>
然后直接在自己主题的functions.php中添加下面的代码:
/* * 缓存时更新浏览量-有缓存 * //www.capjsj.cn/ajax_cookies_views.html */ function postviews_cache(){ if( empty( $_POST['postviews_id'] ) ) return; $post_ID = $_POST['postviews_id']; if( $post_ID > 0 ) { $post_views = (int)get_post_meta($post_ID, 'views', true); /*if( !defined( 'WP_CACHE' ) || !WP_CACHE ){ 以前的错误代码*/ if( defined( 'WP_CACHE' ) && WP_CACHE ){ //如果wp-config.php开启缓存 update_post_meta($post_ID, 'views', ( $post_views + 1 )); } echo ( $post_views + 1 ); exit(); } } add_action( 'wp_ajax_nopriv_postviews', 'postviews_cache' ); add_action( 'wp_ajax_postviews', 'postviews_cache' );
2018年06月07日更新:
感谢网友@鱼鱼 在评论区指出的BUG,以前写上面的代码的时候参考了wp-postviews插件wp-postviews.php里面的代码,结果学艺不精,只看了上半截,忽略了下半截。错误的代码竟然用了近1年的时间没发现,还发布在这里误人子弟,实在羞愧。
上面的代码中,错误的代码依然留存着,只是注释了,修改的方法有两种,第一种是上面那样,第二种则是将10-12行的if段改为下方模式(这种就是wp-postviews插件的写法):
if( defined( 'WP_CACHE' ) && WP_CACHE ) //如果wp-config.php没有开启缓存 return; //退出(中止函数的运行) update_post_meta($post_ID, 'views', ( $post_views + 1 ));
注意,如果网站的WordPress只加入了CDN,没有使用缓存插件的话,需要将上面代码改成下面的,也就是删除开启缓存判断:
/* * 缓存时更新浏览量-无缓存 * //www.capjsj.cn/ajax_cookies_views.html */ function postviews_cache(){ if( empty( $_POST['postviews_id'] ) ) return; $post_ID = $_POST['postviews_id']; if( $post_ID > 0 ) { $post_views = (int)get_post_meta($post_ID, 'views', true); update_post_meta($post_ID, 'views', ( $post_views + 1 )); echo ( $post_views + 1 ); exit(); } }
如果想使用有缓存的版本,想要开启网站缓存,可以选择安装缓存插件,或者直接在网站根目录的wp-config.php中,加入下面这行代码:
define('WP_CACHE', true);
如果网站没有加入CDN,也没有使用缓存插件,那么有两个选项:
1、Ctrl + D 保存本页到书签,待文章变成静态页面后再拿出来看看;2、Ctrl + W 关闭本页,因为除非你要研究代码,本页对你没有什么价值,看看更多该看的吧。
总结
对于本文的解决方案有什么意见和建议,希望能够在下方评论栏中提出来,先森觉得还有能够改进的地方,但一人之力实在有些相形见绌。ajax是个很实用的东西,可能还有更多可以使用的地方,先森也得好好想想。
历史上的今天:
转载请注明出处来自https://www.capjsj.cn/ajax_cookies_views.html
厉害了我的航!
你们不停的优化,我是文章超过2000个字发不了,不知道怎么解决
@在线看小说: wordpress是没有字数限制的啊,我特意搜了一下,也没有太多的案例,更没有解决方法。你是不是无意间加了什么限定函数在主题functions.php里面呢?
@狂族晨曦: 我没有添加任何代码呢,主要是不会添加
博主是一个技术大神啊
谢谢分享,我觉得还是zblog好用.
还是牛逼,会搞
请问下,你这个是前提启用wp-postviews插件才能用,还是有相关字段就可以用呢?
@zlsin: 不好意思,现在才回复。我这里使用的是代码版的wp-postviews,这一点可以看文章开篇处提到的前文。据我查看wp-postviews插件的代码,插件应该是有配置缓存后刷新文章阅读数的,只是没有前台动态更新显示而已。
!defined( ‘WP_CACHE’ ) || !WP_CACHE 这个是否搞错了?我测试开启了缓存,然后手工清除cookies,浏览数依然不变,意思是即使没有cookies存在,它也不会去增加数据库中的浏览数,正常的思路应该是没有cookies时,写入新的浏览数的么??
@鱼鱼: 感谢提醒,确实是个BUG,现在已修改。
!defined( ‘WP_CACHE’ ) || !WP_CACHE
的含义是如果没有开启缓存,这个时候是该中止函数的。一年半了…不容易啊!
&action=postviews 的 postviews 是不是要与后面 php 的 postviews_cache 一致?
感觉像是不会调用functions.php下面的代码,我在functions.php下面的代码加了alert,一直没有提示。会是什么问题?
调用代码是多少