CDN后用Ajax動(dòng)態(tài)提交、顯示文章閱讀量,cookies避免重復(fù)刷新
編輯:狂族晨曦 來源:WordPress技巧 日期:2017-08-29 閱讀: 8,794 次 16 條評論 » 百度已收錄
上篇文章解決了WordPress加入CDN后“非插件瀏覽次數(shù)統(tǒng)計(jì)”瀏覽次數(shù)不刷新問題,同時(shí)留下了兩個(gè)未解決的問題:
1.按F5可無限制刷新文章訪問量,并影響數(shù)據(jù)庫效率;2.只解決了后臺不更新問題,前臺顯示還是得等CDN刷新后才能更新。
那么這篇文章就是為了解決以上兩個(gè)問題。
問題分析
第一個(gè)問題,先森想到的解決方法是用JS代碼創(chuàng)建cookies,如果cookies存在就不在更新后臺的統(tǒng)計(jì)量。
第二個(gè)問題,直接讓ajax獲取后臺的訪問量,修改前臺顯示的訪問量就行了。
一開始,先森配置的讓ajax多傳一個(gè)參數(shù),是判斷cookies是否存在的,存在為1,不存在為0。
若cookies不存在,則后臺訪問量統(tǒng)計(jì)就+1,并返回?cái)?shù)據(jù)庫中的瀏覽量并+1。
若cookies存在,則后臺不增加訪問數(shù)量,直接返回?cái)?shù)據(jù)庫中的瀏覽量并+1,如此訪客刷新也不會(huì)增加訪問量了。
但是這樣還是存在會(huì)在后臺查詢數(shù)據(jù)的問題,查詢多了對數(shù)據(jù)庫也是一種負(fù)擔(dān)。
先森之前沒有意識到這個(gè)問題,結(jié)果還是晚上睡覺前反思發(fā)現(xiàn)了,且也琢磨除了一個(gè)更好的解決方法。
直接在JavaScript代碼中加判斷,如果cookies已存在,則直接不向后端服務(wù)器發(fā)數(shù)據(jù)。這樣一來,前端再怎么刷新,也停留在CDN的層面上。
那么要實(shí)現(xiàn)這種效果,就需要先實(shí)現(xiàn)不向后端服務(wù)器發(fā)送數(shù)據(jù),也能獲取到當(dāng)前文章的訪問量。解決方法很簡單,第一次獲取訪問量時(shí),將后端服務(wù)器返回的訪問量直接寫入cookies,下次刷新時(shí),直接從cookies中讀取訪問量。
另外,還有一個(gè)地方需要解釋一下,cookies的過期時(shí)間。如果cookies時(shí)間太長了的話,那么未免還是會(huì)損失一些訪問量,所以先森就沒有設(shè)置cookies的過期時(shí)間,保持默認(rèn)。cookies的默認(rèn)過期為關(guān)閉瀏覽器,先森覺得,這樣一來還是比較合理的。
同時(shí),一個(gè)訪客,可能并不會(huì)只打開本站一篇文章就關(guān)閉,打開多篇文章時(shí),每篇文章的訪問量是不一樣的,需要從cookies中獲取的話,cookies的名稱就必須不一樣。不然訪問打開其他文章,看到了訪問量都是同一個(gè)數(shù)值。解決方法就是,已“固定值+文章ID”的方式,確定cookies名稱的唯一。
效果實(shí)現(xiàn)
上一篇文章中,先森是模仿通用的評論ajax提交的處理方式,自建了一個(gè)類似的php。但這樣可能有點(diǎn)不安全,也有點(diǎn)麻煩,所以先森還是研究著將php代碼部分放進(jìn)了主題的functions.php。
首先還是在footer.php中添加ajax的代碼,注意需要將前臺顯示訪問量的標(biāo)簽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中添加下面的代碼:
/*
* 緩存時(shí)更新瀏覽量-有緩存
* //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 ){ 以前的錯(cuò)誤代碼*/
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日更新:
感謝網(wǎng)友@魚魚 在評論區(qū)指出的BUG,以前寫上面的代碼的時(shí)候參考了wp-postviews插件wp-postviews.php里面的代碼,結(jié)果學(xué)藝不精,只看了上半截,忽略了下半截。錯(cuò)誤的代碼竟然用了近1年的時(shí)間沒發(fā)現(xiàn),還發(fā)布在這里誤人子弟,實(shí)在羞愧。
上面的代碼中,錯(cuò)誤的代碼依然留存著,只是注釋了,修改的方法有兩種,第一種是上面那樣,第二種則是將10-12行的if段改為下方模式(這種就是wp-postviews插件的寫法):
if( defined( 'WP_CACHE' ) && WP_CACHE ) //如果wp-config.php沒有開啟緩存 return; //退出(中止函數(shù)的運(yùn)行) update_post_meta($post_ID, 'views', ( $post_views + 1 ));
注意,如果網(wǎng)站的WordPress只加入了CDN,沒有使用緩存插件的話,需要將上面代碼改成下面的,也就是刪除開啟緩存判斷:
/*
* 緩存時(shí)更新瀏覽量-無緩存
* //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();
}
}
如果想使用有緩存的版本,想要開啟網(wǎng)站緩存,可以選擇安裝緩存插件,或者直接在網(wǎng)站根目錄的wp-config.php中,加入下面這行代碼:
define('WP_CACHE', true);
如果網(wǎng)站沒有加入CDN,也沒有使用緩存插件,那么有兩個(gè)選項(xiàng):
1、Ctrl + D 保存本頁到書簽,待文章變成靜態(tài)頁面后再拿出來看看;2、Ctrl + W 關(guān)閉本頁,因?yàn)槌悄阋芯看a,本頁對你沒有什么價(jià)值,看看更多該看的吧。
總結(jié)
對于本文的解決方案有什么意見和建議,希望能夠在下方評論欄中提出來,先森覺得還有能夠改進(jìn)的地方,但一人之力實(shí)在有些相形見絀。ajax是個(gè)很實(shí)用的東西,可能還有更多可以使用的地方,先森也得好好想想。
歷史上的今天:
轉(zhuǎn)載請注明出處來自http://www.cnidcc.cn/ajax_cookies_views.html

川公網(wǎng)安備 51011202000104號
厲害了我的航!
你們不停的優(yōu)化,我是文章超過2000個(gè)字發(fā)不了,不知道怎么解決
@在線看小說: wordpress是沒有字?jǐn)?shù)限制的啊,我特意搜了一下,也沒有太多的案例,更沒有解決方法。你是不是無意間加了什么限定函數(shù)在主題functions.php里面呢?
@狂族晨曦: 我沒有添加任何代碼呢,主要是不會(huì)添加
博主是一個(gè)技術(shù)大神啊
謝謝分享,我覺得還是zblog好用.
還是牛逼,會(huì)搞
請問下,你這個(gè)是前提啟用wp-postviews插件才能用,還是有相關(guān)字段就可以用呢?
@zlsin: 不好意思,現(xiàn)在才回復(fù)。我這里使用的是代碼版的wp-postviews,這一點(diǎn)可以看文章開篇處提到的前文。據(jù)我查看wp-postviews插件的代碼,插件應(yīng)該是有配置緩存后刷新文章閱讀數(shù)的,只是沒有前臺動(dòng)態(tài)更新顯示而已。
!defined( ‘WP_CACHE’ ) || !WP_CACHE 這個(gè)是否搞錯(cuò)了?我測試開啟了緩存,然后手工清除cookies,瀏覽數(shù)依然不變,意思是即使沒有cookies存在,它也不會(huì)去增加數(shù)據(jù)庫中的瀏覽數(shù),正常的思路應(yīng)該是沒有cookies時(shí),寫入新的瀏覽數(shù)的么??
@魚魚: 感謝提醒,確實(shí)是個(gè)BUG,現(xiàn)在已修改。
!defined( ‘WP_CACHE’ ) || !WP_CACHE的含義是如果沒有開啟緩存,這個(gè)時(shí)候是該中止函數(shù)的。一年半了…不容易啊!
&action=postviews 的 postviews 是不是要與后面 php 的 postviews_cache 一致?
感覺像是不會(huì)調(diào)用functions.php下面的代碼,我在functions.php下面的代碼加了alert,一直沒有提示。會(huì)是什么問題?
調(diào)用代碼是多少