CDN后用Ajax動態提交、顯示文章閱讀量,cookies避免重復刷新
編輯:狂族晨曦 來源:WordPress技巧 日期:2017-08-29 閱讀: 8,797 次 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.cnidcc.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.cnidcc.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是個很實用的東西,可能還有更多可以使用的地方,先森也得好好想想。
歷史上的今天:
轉載請注明出處來自http://www.cnidcc.cn/ajax_cookies_views.html

川公網安備 51011202000104號
厲害了我的航!
你們不停的優化,我是文章超過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,一直沒有提示。會是什么問題?
調用代碼是多少