相关文章推荐
豁达的小马驹  ·  OSS设置跨域资源共享CORS_对象存储(O ...·  3 周前    · 
眉毛粗的跑步鞋  ·  公共机构节约能源资源网·  4 月前    · 
气势凌人的跑步机  ·  解决报错:org.apache.catali ...·  7 月前    · 
读研的水煮鱼  ·  前端实现打印 - 跟着姐姐走 - 博客园·  1 年前    · 
低调的沙发  ·  python - ...·  2 年前    · 
开朗的竹笋  ·  AI扩展图片 - 知乎·  2 年前    · 
Code  ›  启用WP Super Cache纯代码版本之后的一些优化措施开发者社区
post url 代码优化 浏览器缓存
https://cloud.tencent.com/developer/article/1071258?areaSource=106001.20
刀枪不入的核桃
2 年前
作者头像
张戈
0 篇文章

启用WP Super Cache纯代码版本之后的一些优化措施

前往专栏
腾讯云
备案 控制台
开发者社区
学习
实践
活动
专区
工具
TVP
文章/答案/技术大牛
写文章
社区首页 > 专栏 > 张戈的专栏 > 正文

启用WP Super Cache纯代码版本之后的一些优化措施

发布 于 2018-03-23 14:55:47
861 0
举报

张戈博客在上个月 28 号启用了 WP Super Cache 代码版,几天下来,虽然小问题不断,但是总体感觉非常不错!不管是前台还是后台,速度都有质的提升,着实值得会折腾的人使用。

感兴趣的可以先看下 28 号的具体教程:《WP Super Cache 静态缓存插件纯代码版(兼容多 域名 网站)》.

下面,简单的说一下启用此功能后遇到的一些问题的解决办法或细项优化。

①、发表评论时并未删除缓存,导致无法显示最新评论; ②、若主题有登陆状态显示,那缓存之后,无论谁打开都显示已登录; ③、WordPress 原生评论框已登录状态将带入缓存当中,效果同上; ④、管理员回复评论也会发送邮件给管理员(①、②项处理 OK 之后发现的问题); ⑤、无法保存评论者信息,这个是开启缓存之后的诟病,之前已分享过变相解决办法。

以上问题上一篇文章已有具体说明,下面是最新发现的问题:

⑥、居然会缓存评论填表信息; ⑦、缓存清理不够方便; ⑧、缓存没有时间戳; ⑨、发布/更新文章未删除缓存,导致无法显示最新内容; ⑩、开启缓存之后,首页加上 index.php 后缀仍然可以访问,从而造成收录重复; ⑾、会缓存不存在的页面(404),可能被搜索引擎抓取造成 SEO 影响(缓存之后会是 200 状态); ⑿、带补充

一、过滤用户信息

针对第⑥条:

今天,用浏览器无痕模式打开留言板意外发现如图尴尬:

之前浏览器一直是有 cookies,所以每次打开时,博客的 js 都会自动加载已保存的信息,也就是我的经常用的信息。今天鬼使神差的试了下无痕模式,才发现了这个 BUG,尼玛把其他人填写的信息都给缓存了,这是泄漏他人隐私啊!而且也对新用户体验很差!

仔细看了下缓存代码,懒得深究为何会缓存用户浏览器的内容,直接在 cache.php 中加入了置空机制,搞定这个问题:

function auto_cache($contents){//回调函数,当程序结束时自动调用此函数
   global $cache_file;
   $fp = fopen($cache_file,'wb');
   //新增替换代码 Start
   //①. 替换已缓存的用户头像路径为默认
   $contents = preg_replace('/<img id="real-time-gravatar" src=".*?"/','<img id="real-time-gravatar" src="//res.zgboke.com/wp-content/themes/HotNewspro/images/default_avatar.jpg"',$contents);
   //②. 置空已缓存的用户名称
   $contents = preg_replace('/<input type="text" name="author" id="author" class="commenttext" value=".*" size="22" tabindex="1" \/>/','<input type="text" name="author" id="author" class="commenttext" value="" size="22" tabindex="1" \/>',$contents);
   //③. 置空已缓存的用户邮箱
   $contents = preg_replace('/<input type="text" name="email" id="email" class="commenttext" value=".*" size="22" tabindex="2" \/>/','<input type="text" name="email" id="email" class="commenttext" value="" size="22" tabindex="2" \/>',$contents);
   //④. 置空已缓存的用户网址
   $contents = preg_replace('/<input type="text" name="url" id="url" class="commenttext" value=".*" size="22" tabindex="3" \/>/','<input type="text" name="url" id="url" class="commenttext" value="" size="22" tabindex="3" \/>',$contents);
   //新增替换代码 End
   fwrite($fp,$contents);
   fclose($fp);
   chmod($cache_file,0777);
   clean_old_cache(); //生成新缓存的同时,自动删除所有的老缓存。以节约空间。
   return $contents;
}

使用方法 :编辑上一篇文章中所说的 cache.php 文件,搜索 function auto_cache()函数,并替换为以上代码即可。

代码原理 :就是在缓存内容之前,先将已保存的用户信息置空,这样处理之后,缓存到磁盘里的 html 文件才是纯净无痕的。

替换机制也很简单,就是借用了 php 的正则替换函数:preg_replace(),其语法如下:

preg_replace('/搜索字符串/','替换字符串','全部内容')

比如,需要将 hello word! 替换为 hello zhangge!,则可以这样写:

preg_replace('/world/','zhangge','hello world!')

因此,我需要置空缓存内容中的用户名、邮箱及网址,也就是一个最简单的正则匹配过程,比如替换用户名:

//搜索条件中只用了一个正则匹配,那就是value=".*"
$contents = preg_replace('/<input type="text" name="author" id="author" class="commenttext" value=".*" size="22" tabindex="1" \/>/','<input type="text" name="author" id="author" class="commenttext" value="" size="22" tabindex="1" \/>',$contents);

所以,如果你在使用代码版的缓存功能之后,发现某些内容被意外缓存了,只要使用这个方法替换掉即可。

二、前台缓存清理

针对第⑦条

清理缓存不方便的问题,我今天写了一个 js+ajax+php 的方法,可以在前台 ajax 删除缓存内容:

①、新增 JS+ajax 代码:

<script type="text/javascript">
var cache = null;
    if(is_single()){
	echo "var page_type = 'single';";
	echo "var page_slug = 'null';";
    } else if(is_page()){ 
	$post_data = get_post($post->ID, ARRAY_A);
	$slug = $post_data['post_name'];
	echo "var page_type = 'page';";
	echo "var page_slug = '".$slug."';";
    } else if(is_category()){
        $cat = get_query_var('cat');
        $theCat = get_category($cat);
        echo "var page_slug = '".$theCat->slug."';";
	echo "var page_type = 'category';";
    } else if(is_home()){ 
        echo "var page_type = 'home';";
	echo "var page_slug = 'null';";
    } else {
	echo "var page_type = 'null';";
	echo "var page_slug = 'null';";
echo "var post_id = ".$post->ID.";";
echo "var page_name = cache_".$post->ID.";";
//触发函数:点击id为clean元素时将清理该页面缓存
$(function(){ 
    $("#clean").click(function(){ 
            CleanUp();
//ajax清理函数
function CleanUp(){
    $.ajax({
        type:'POST',
        data:{
            "action": "delcache",
            "page_type": page_type,
            "post_id": post_id,
            "slug": page_slug,
        //ajax对象文件:cache.php,即上一篇文章中的静态缓存的php文件
        url: '/cache.php',
        cache: false, 
        error: function(){ 
            alert('发生意外错误!'); 
            return false; 
        success:function(){
            alert('清理成功!确定后将自动刷新本页...');
            location.reload(true);
</script>

将以上代码添加到主题 footer 或合并到其他 js 当中均可,需要注意的是,在此代码之前必须先正常载入 Jquery。

②、新增 php 代码:

//缓存清理代码(实际使用,请自行修改缓存路径!)
if(isset($_POST['action'])){
    if($_POST['action'] == 'delcache'){
        if($_POST['page_type'] == 'single'){
            $post = $_POST['post_id'];
            $cachefile = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$post.".html/index.html";
            $cachedir = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$post.".html";
        } else if($_POST['page_type'] == 'page') {
            $post = $_POST['slug'];
            $cachefile = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$post."/index.html";
            $cachedir = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$post;
        } else if($_POST['page_type'] == 'category') {
            $post = $_POST['slug'];
            $cachefile = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$post."/index.html";
            $cachedir = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$post;
        } else if($_POST['page_type'] == 'home') { 
            $cachefile = "/home/wwwroot/zhangge.net/cache/zhangge.net/index.html";
        } else {
            exit();
        if($_POST['page_type'] == 'home'){
            if (file_exists($cachefile)) {
                unlink($cachefile);
        } else if($_POST['page_type'] != 'null') {
            if (file_exists($cachefile)) {
                unlink($cachefile);
                rmdir($cachedir);
        } else {
           exit(); 
    exit();
}

将以上代码添加到静态缓存文件 cache.php 的<?php 之后即可。

注意:cache.php 和 js 代码中的 url 对象是 一 一对应的!!这篇文章主要是针对上一篇文章而写的,所以就是 cache.php,如果想改成其他 php 文件,也是可以的,但前提条件是和 js 中 url 对象要一致!

③、新增触发按钮

在文章、单页页面,合适的位置新增一个按钮或超链接,然后将其 id 改为 clean 即可实现点击该按钮时清理当前页面缓存,比如张戈博客将一个图片链接放到了百度分享工具条上(实现全局清理后,我将其移动到了右下角滚动条):

最简单的写法如下:

<img src="图片路径" id="clean">

你也可以在其他空闲元素上新增一个 id="clean",总之就是要新增一个 id 为 clean 的元素!在网站前台点击这个元素将清除当前页面的缓存。

三、加入缓存时间

针对第⑧条:

如果缓存页面没有时间戳,会让人分不清楚这个缓存页面是什么时候生成的,因为有时删除了缓存文件,在前台刷新看到的依然是缓存内容(nginx 通常会产生一个 304 的浏览器缓存)!如果有个时间戳,就能更加容易的区分是否是最新的缓存。

解决方法很简单,在缓存时在代码最后新增时间戳即可,和 WP Super Cache 一样!

和上文第一条过滤用户信息的操作一样,找到 auto_cache 函数,如下新增 2 行时间戳代码即可:

function auto_cache($contents){         //回调函数,当程序结束时自动调用此函数
   global $cache_file;
   $fp = fopen($cache_file,'wb');
   $contents = preg_replace('/<img id="real-time-gravatar" src=".*?"/','<img id="real-time-gravatar" src="//res.zgboke.com/wp-content/themes/HotNewspro/images/default_avatar.jpg"',$contents);
   $contents = preg_replace('/<input type="text" name="author" id="author" class="commenttext" value=".*" size="22" tabindex="1" \/>/','<input type="text" name="author" id="author" class="commenttext" value="" size="22" tabindex="1" \/>',$contents);
   $contents = preg_replace('/<input type="text" name="email" id="email" class="commenttext" value=".*" size="22" tabindex="2" \/>/','<input type="text" name="email" id="email" class="commenttext" value="" size="22" tabindex="2" \/>',$contents);
   $contents = preg_replace('/<input type="text" name="url" id="url" class="commenttext" value=".*" size="22" tabindex="3" \/>/','<input type="text" name="url" id="url" class="commenttext" value="" size="22" tabindex="3" \/>',$contents);
   //如下新增2行代码即可在缓存页面的最后输出时间戳!
   date_default_timezone_set('Asia/Shanghai'); 
   $contents.="\n<!-- Power By WordPress纯静态缓存代码,生成日期:".date('Y-m-d h:i:s',time())." -->";  
   fwrite($fp,$contents);
   fclose($fp);
   chmod($cache_file,0777);
   clean_old_cache();                  //生成新缓存的同时,自动删除所有的老缓存。以节约空间。
   return $contents;
}

四、发布时删除缓存

针对第⑨条:

这个问题其实很好解决,只要使用 WordPress 钩子在发布或更新文章时,调用删除缓存函数即可,具体如下:

//发布或更新文章时删除文章、首页和对应分类缓存
function DelSingleCache($post_ID){
    $category = get_the_category();
    $slug = $category[0]->category_nicename;
    if($slug=='itnews' || $slug=='feeling') {
        $real_slug = "others/".$slug;
    } else if ($slug=='web' || $slug=='os' || $slug=='db') {
        $real_slug = "op/".$slug;
    } else {
            $real_slug = $slug;
    $single_file = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$post_ID.".html/index.html";
    $single_dir = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$post_ID.".html";
    $cat_file = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$real_slug."/index.html";
    $cat_dir = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$real_slug;    
    $home_cache = "/home/wwwroot/zhangge.net/cache/zhangge.net/index.html";
    $m_single_file = "/home/wwwroot/zhangge.net/cache/m.zhangge.net/".$post_ID.".html/index.html";
    $m_single_dir = "/home/wwwroot/zhangge.net/cache/m.zhangge.net/".$post_ID.".html";    
    $m_cat_file = "/home/wwwroot/zhangge.net/cache/m.zhangge.net/".$real_slug.".html/index.html";
    $m_cat_dir = "/home/wwwroot/zhangge.net/cache/m.zhangge.net/".$real_slug.".html";          
    $m_home_cache = "/home/wwwroot/zhangge.net/cache/m.zhangge.net/index.html";    
    if (file_exists($single_file)) {
        unlink($single_file);
        rmdir($single_dir);
    if (file_exists($m_single_file)) {
        unlink($m_single_file);
        rmdir($m_single_dir);
    if (file_exists($home_cache)) {
        unlink($home_cache);
    if (file_exists($m_home_cache)) {
        unlink($m_home_cache);
    if (file_exists($cat_file)) {
        unlink($cat_file);
        rmdir($cat_dir);
    if (file_exists($m_cat_file)) {
        unlink($m_cat_file);
        rmdir($m_cat_dir);
    exec(EscapeShellCmd("/opt/reload_nginx.sh"));  
add_action('publish_post', 'DelSingleCache');
//发布或更新页面时删除页面缓存
function DelPageCache($post_ID){
    $post_data = get_post($post->ID, ARRAY_A);
    $slug = $post_data['post_name'];
    $page_file = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$slug."/index.html";
    $page_dir = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$slug;    
    $m_page_file = "/home/wwwroot/zhangge.net/cache/m.zhangge.net/".$slug."/index.html";
    $m_page_dir = "/home/wwwroot/zhangge.net/cache/m.zhangge.net/".$slug;
    if (file_exists($page_file)) {
        unlink($page_file);
        rmdir($page_dir);
    if (file_exists($m_page_file)) {
        unlink($m_page_file);
        rmdir($m_page_dir);
    exec(EscapeShellCmd("/opt/reload_nginx.sh"));  
add_action('publish_page', 'DelPageCache');

将以上代码添加到主题目录的 functions.php 中即可实现发布或更新文章(单页面)的时候,删除当前文章(页面)、首页及所在分类的缓存文件,比 WP Super Cache 的那个发布文章删除所有缓存的机制合理多了!!

Ps:关于删除缓存的所有代码中(包括前面的 ajax 清理功能),若存在二级分类,那么分类缓存路径可能需要进一步修改一下,才会更准确,如果你不清楚,那么用上面的代码也没有任何问题!

以下是张戈博客分类缓存路径的改进案例,仅供参考:

//根据张戈博客分类实际情况,itnews/feeling/web/os/db这些分类都是二级分类,所以需要加上其父分类路径:
if($slug=='itnews' || $slug=='feeling') {
   $real_slug = "others/".$slug;
} else if ($slug=='web' || $slug=='os' || $slug=='db') {
   $real_slug = "op/".$slug;
} else {
   $real_slug = $slug;
$cat_file = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$real_slug."/index.html";
$cat_dir = "/home/wwwroot/zhangge.net/cache/zhangge.net/".$real_slug;

五、index.php 跳转

针对第⑩条

今天,在看百度收录的时候,突然看到如下情形:

试了下,没开启缓存的博客在首页后面加上 index.php 访问,是会自动跳到不带 index.php 的,即访问 http://yourdomain.com/index.php 会自动跳到 http://yourdomain.com/。

但是开启这个代码缓存之后,带上 index.php 是不会跳转的,我估计 wp super cache 的缓存也有这个问题。好吧,说下解决办法:

①、最简单的方法:

直接在 robots.txt 里面禁止百度抓取即可(不过不怎么绝对!):

Disallow: /index.php

Ps:实际上,我的 robots.txt 里面本来就有一条:

Disallow: /*.php$

尼玛百度就是这么任性!!!不遵守协议。

②、301 跳转方法:

试了半天 nginx,发现和之前写的规则存在冲突,无奈之下只好用 php 代码实现 301 跳转:

//避免index.php也可以访问带来的SEO问题
$the_host = $_SERVER['HTTP_HOST'];
$the_url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
$the_host = strtolower($the_host);
$the_url = strtolower($the_url); 
if($the_url=="/index.php") {
    header('HTTP/1.1 301 Moved Permanently');
 
推荐文章
豁达的小马驹  ·  OSS设置跨域资源共享CORS_对象存储(OSS)-阿里云帮助中心
3 周前
眉毛粗的跑步鞋  ·  公共机构节约能源资源网
4 月前
气势凌人的跑步机  ·  解决报错:org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe-CSDN博客
7 月前
读研的水煮鱼  ·  前端实现打印 - 跟着姐姐走 - 博客园
1 年前
低调的沙发  ·  python - win32com处理word中的复杂表格 - SegmentFault 思否
2 年前
开朗的竹笋  ·  AI扩展图片 - 知乎
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号