成航先森 成航先森

成都航院计算机系一个学生的个人博客

 

随便看看:

分段图 CDNkeepalivedLinuxmysqlnginxrsyncUEditorWordPressWordPress插件七牛体育部信息志愿服务队免流全体例会向党组织靠拢团学会学习部宣传部影视相关心理部成都航院报社招生信息教学资源文艺部毕业就业流量活动生活杂谈社会实践部站长经历系部介绍系部动态纪检部组织部经验分享老师腾讯云资源下载轻松时刻高考录取分数线

标签:CDN

慎用百度云观测 竟把网站拖垮

经验杂笔慎用百度云观测 竟把网站拖垮

标签:, | 5 条评论 | 2017-09-13

先森的网站还是放在阿里云免费云虚拟主机,每个月被关停之后,只能启动三次。先森上一次被关停是7月份的事情,没想到昨天凌晨,噩梦又来袭。早上先森上班之后,抽空看了一下网站的日志。因为阿里云的提示短信是凌晨三点四十多发的短信,所以先森重点关注这个时间段的,然后就发现了罪魁祸首,这篇文章的主角——百度云观测。坑爹的百度云观测在日志中,我发现了大量的请求,全是User-Agent:Baidu-YunGuanCe-ScanBot(ce.baidu.com),而且访问的还都是/wp-comments-post.php和/wp-admin/admin-ajax.php这些会接收数据,查询、修改数据库的php文件,这样一来对网站的压力就非常的大了。来自百度云观测的大量请求这种情况,先森赶紧去百度云观测把网站监控关闭,百度云观测的骚操作太恐怖了。关闭百度云观测后续先森在百度云观测找到这样的一段话,先森感觉心中一万只。。。。网站初始化包含多个分析过程,一般需要5~10分钟。 网站初始化时,我们会对你的网站进行全方位安全体检。初始化这段时间内,可能会向你的网站发送一定攻击探测请求,以发现安全漏洞。 一般情况下,正常网站不会因为安全体检受到任何影响。后来,昨天下午先森的网站又被关停了一次,这一次,不是百度云观测的锅了,先森已经关了。这次,是有人在拿先森网站练手,搞DDOS,先森看日志,发现大量的125.39.239.*网段的请求。因为网站放在百度云CDN,免费版又不能设置黑白名单,所以先森只把防守放在了.htaccess文件里面,但是先森发现,放在里面并无卵用,有了CDN,该访问还是能访问。所以先森还是把网站CDN都解析到腾讯云CDN。腾讯云CDN对移动宽带的支持貌似不太友好,但是好在是能够配置黑白名单,有这点就够了。

CDN后用Ajax动态提交、显示文章阅读量,cookies避免重复刷新

WordPress技巧CDN后用Ajax动态提交、显示文章阅读量,cookies避免重复刷新

标签:, , | 12 条评论 | 2017-08-29

上篇文章解决了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中添加下面的代码:/** 缓存时更新浏览量-有缓存* http://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,没有使用缓存插件的话,需要将上面代码改成下面的,也就是删除开启缓存判断:/** 缓存时更新浏览量-无缓存* http://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是个很实用的东西,可能还有更多可以使用的地方,先森也得好好想想。

解决WordPress加入CDN后“非插件浏览次数统计”浏览次数不刷新问题

WordPress技巧解决WordPress加入CDN后“非插件浏览次数统计”浏览次数不刷新问题

标签:, , | 6 条评论 | 2017-08-25

不知道多少人和先森一样,在最初接触wordpress的时候,被网上的各类教程灌输了“能用代码版,就不用插件”的概念。先森就本着这个概念,在文章的访问量的时候,先森就找的代码版。网上提供的代码版浏览次数统计功能的文章,名称都差不多,类似“WordPress非插件添加文章浏览次数统计功能”这种比比皆是。先森应该是在wordpress大学看到的教程,关于教程先森就不再赘述了。本文主要解决的是,开启CDN后,用这种代码版访问量统计的方式浏览次数不再刷新的问题,如果想结合着来使用的话,统计代码部分可以去wordpress大学看《WordPress非插件添加文章浏览次数统计功能》这篇文章。浏览次数问题分析先森其实很早就意识到,开启CDN后,其实浏览量不是不刷新,而是只在首次缓存的时候才会增加一次。因为只有第一次访问的时候才会执行php,缓存后就直接访问的html了,所以就不会增加统计了。所以解决问题的方式,是让html也能统计到浏览次数,先森认知中的方法就只有一个:ajax。然而当初先森虽然知道问题原因,知道解决方式,但奈何先森代码能力不强,当时没能解决。先森始终认为,一个问题如果死活解决不了,那么就先放放,过段时间再反顾可能就会发现,这个问题根本就不是事。当然,这个时间可能就有点久了,起码就ajax这个问题,先森等了一两年。。。。先森想到的用ajax更新浏览次数的方法就是,使用ajax提交文章的ID给后方的php,后方的php接收到文章ID后,将该文章的浏览次数+1。效果实现先森研究了一晚上,发现要解决还是挺简单的。又是研究几小时,分享几分钟,心塞。首先,在footer.php中添加ajax的代码,注意url的地址要改为自己的php路径:<?php if  (is_singular()) : ?>  <!-- ajax post view -->  <!-- ajax post view -->  <script type= "text/javascript" >$.ajax({ type:'POST', url: "http://www.capjsj.cn/wp-content/themes/*/*.php" ,   /*此处需要修改为自己的php路径*/data: { "postviews_id" : "<?php the_ID();?>" } });   </script><?php endif ; ?>接收数据的php代码很简单,参考了评论的comments-ajax.php的头部,禁止直接访问,然后加上了几行更新浏览量的代码。将下面内容保存到一个php文件中,放入自己的wordpress主题里面,将该php的访问链接加入到上面的url中:<?php//禁止直接访问本phpif ( 'POST' != $_SERVER['REQUEST_METHOD'] ) {        header('Allow: POST');        header('HTTP/1.1 405 Method Not Allowed');        header('Content-Type: text/plain');        exit;}require( dirname(__FILE__) . '/../../../wp-load.php' );nocache_headers();$post_ID = $_POST['postviews_id'];$post_views = (int)get_post_meta($post_ID, 'views', true);update_post_meta($post_ID, 'views', ($post_views+1));?>如此一来,即使加入了CDN,文章页面变成了静态页面,后台也会更新访问次数了。总结这样仅仅是解决了文章页面被缓存后,浏览次数无法被统计到的问题,但是还并不完善。上面的功能实现之后,你会发现,每一次刷新浏览次数都会加一,如果有人一直按着F5,那么增加的浏览次数就有点恐怖了。这样还会增加服务器的负担,像先森这种把网站放在阿里云虚拟主机的,若负载过量还会直接关停,被人这样搞的关机先森就哭了。所以,下篇文章先森会分享使用cookies来限制访问次数无限增加的问题。另外,除了访问量持续增加的问题,还有一个地方可以优化。既然ajax能够异步提交数据,那么能不能动态的修改文章中的浏览次数呢?答案是肯定的,先森也会在下一篇文章中更新。关于上面的问题,请查看下一篇文章:CDN后用Ajax动态提交、显示文章阅读量,cookies避免重复刷新

WordPress让管理员在前台匿名,避免CDN缓存

WordPress技巧WordPress让管理员在前台匿名,避免CDN缓存

标签:, | 6 条评论 | 2017-08-23

自从用上CDN,需要关注的前台页面的问题就更多了,因为要避免一些不该被CDN缓存的内容被缓存,导致访客访问到不该看到的内容,影响使用体验。最近,先森发现曾解决过的问题故态复萌。用了CDN之后比较突出的问题,就是如果一篇文章如果先森登录之后再去访问,其他访客访问的时候,会显示“内容管理”、“登出”、评论框会显示先森的头像等问题。这个问题其实之前已经处理过了,但是先森wordpress升级之后,发现原本通过WP Super Cache设置的“不要为已知用户缓存”和“让已知用户匿名使他们浏览的内容是缓存文件”竟然失效了。查看了下WP Super Cache的版本,发现四周前才更新,并且提示与当前WordPres版本兼容,先森也确定选项已经勾选,但就是不生效,所以就很心塞。发现问题,处理问题。先森冒着英语超烂的风险,去了WP Super Cache的插件页面,看了一圈问题讨论,就是没发现有人提这个BUG的,在官方找解决方案的道路失败了。也不知道新的版本什么时候发布,发布会不会包含解决这个问题,所以先森只能又冒着php一知半解的风险来写代码了。解题思路解决方式先森觉得有两种,一个是去把自己的主题中的前台中管理员登录后才会显示的代码给删掉,另一种就是让管理员在前台匿名,被认为没有登录。第一种方案,先森觉得有点费时费力。当初主题的代码是自己一行一行的写的,现在让自己去删,内心表示很痛苦啊(心中憧憬着哪天要是不用CDN了...)。所以先森还是想实现第二种方案。经过研究自己的主题,先森发现,会显示管理员才能看到的东西,大多使用了这样的一种套路:<?php if (is_user_logged_in()){    '我是管理员'} ?>都用的is_user_logged_in()这个函数来判断用户是否登录,所以先森就想,让这个函数返回“用户没有登录”岂不是就可以了?is_user_logged_in()函数介绍:is_user_logged_in()函数位于wp-includes/pluggable.php函数参数:该函数不接受任何参数。返回值:已登陆返回True,否则返回False。先森在函数所在位置,找到了这个函数的代码:if ( !function_exists('is_user_logged_in') ) :/** * Checks if the current visitor is a logged in user. * * @since 2.0.0 * * @return bool True if user is logged in, false if not logged in. */function is_user_logged_in() {        $user = wp_get_current_user();        return $user->exists();}endif;先森把上面的return内容改成了如下内容:if(!is_admin()){    return false;}else{return $user->exists();}这样之后,只要不是后台,就会返回false,这样前台就会得到管理员没有登录。先森发现使用了is_user_logged_in()函数的位置都已经不会在登录的情况下显示了,但是还有两个地方例外。第一个地方是文章页面上的“编辑”按钮,另一个就是评论的头像了。通过查看代码,先森发现编辑按钮用的是edit_post_link()函数:edit_post_link('编辑', ' &#124; ', '');函数说明:若用户已登录且具有编辑文章的权限,该标签显示一个可编辑当前文章的链接。该标签必须用在主循环(loop)中。这个函数就没有使用is_user_logged_in()函数了,所以通过修改is_user_logged_in()的返回值就对“编辑”按钮不生效了。再来看评论头像。修改了is_user_logged_in()的返回值之后,头像旁边的文字已经变成了未登录状态下的文字,但是头像依然是先森的管理员评论头像。再去查看代码,发现评论头像部分虽然也使用了is_user_logged_in()函数,但是还另外使用了一个全局变量,代码大致如下:global $current_user;get_currentuserinfo();...echo get_avatar( $current_user->user_email, $size = '48' ,'');这样是通过获取当前用户信息,然后来获取用户的email邮箱地址,这样就和is_user_logged_in()函数无关了,因此前台还是会显示管理员的头像。但也正是这个问题,让先森找到了解决的办法。让管理员在前台匿名评论头像是通过获取当前登录用户的相关信息,进而获取用户邮箱来显示头像的。用到的获取用户信息函数是:get_currentuserinfo()而其实看is_user_logged_in()函数,其实它也有获取当前用户的相关信息,但用的是另一个函数:$user = wp_get_current_user();而这两个函数,其实是同一个函数,只是wp_get_current_user()是get_currentuserinfo()的进阶版:Notice: 自4.5.0版本起,已不建议使用get_currentuserinfo,请换用wp_get_current_user()。 in ***\wp-includes\functions.php on line 3707既然如此,只需要让当前用户信息为空即可。在自己的主题function.php最后加入以下代码,那么在前台就用户信息就为空了,即获取不到用户信息了:/*** 让管理员在前台访问匿名** http://www.capjsj.cn/make_known_users_anonymous.html*/function make_known_users_anonymous() {    global $current_user; if(!is_admin()){    $current_user = array( 'user_login' => '', 'user_email' =>'', 'user_level' => '', 'user_firstname' => '', 'user_lastname' => '', 'display_name' => '', 'ID' => '', 'user_url' => '', ); } return $current_user;}add_action( 'init', 'make_known_users_anonymous' );如果想要调试的话,可以把以下代码放在前台页面中想放的位置:<?php  global $current_user; get_currentuserinfo(); //或者将这两行换成 $current_user = wp_get_current_user();if( is_user_logged_in()){    echo '已经登录';}else{    echo '没有登录';}echo('Username: ' . $current_user->user_login . "\n"); //输出用户名  ?>但目前这种方式有个BUG,那就是在文章编辑页面点击预览的时候会返回404,这个待先森找找解决方法。2017-09-01更新先森看了下,预览的页面会在文章链接后面加上“?preview=true”或者“?p=xxx&preview=true”,那么,当访问链接是带了“preview=true”的,就不清除登录信息就行了。那么,把上面的匿名代码改成下面的代码,加入functions.php中/*** 让管理员在前台访问匿名** http://www.capjsj.cn/make_known_users_anonymous.html*/function make_known_users_anonymous() {    global $current_user; if(!is_admin() && $_GET['preview'] != 'true'){    $current_user = array( 'user_login' => '', 'user_email' =>'', 'user_level' => '', 'user_firstname' => '', 'user_lastname' => '', 'display_name' => '', 'ID' => '', 'user_url' => '', ); } return $current_user;}add_action( 'init', 'make_known_users_anonymous' );如果有任何问题,可以在下方评论。关于访客填写的昵称、邮箱、域名等信息不被CDN缓存,可以看看先森的解决方案:用cookie解决网站开启CDN缓存之后已知用户头像昵称被缓存等系列问题用cookie记住用户信息后隐藏信息输入框,优化用户体验

新版Linux/vps本地十五天循环备份和七牛远程备份脚本

WordPress技巧新版Linux/vps本地十五天循环备份和七牛远程备份脚本

标签:, , , | 2 条评论 | 2017-08-20

最新在新建一个博客,新的博客是建在云服务器的,完全自主,不得不说感觉非常好,比起虚拟主机可操作性强太多了。因为可操作性强,所以想把该做的都做好,比如备份。受张戈博客影响,看到了张戈的同步7天的那篇文章,想照着操作的时候发现,七牛的qrsync工具竟已废弃:qrsync已废弃看这简介,推荐使用qshell命令行工具,先森就干脆研究下使用新的工具来同步。有段时间没和七牛云储存打交道了,变化还是挺大的。为七牛的推陈出新点个赞。一、数据库、网站本地备份脚本在服务器上编辑shell脚本,脚本代码如下:#!/bin/bash# Name:liuxxbak.sh# This is a ShellScript For Auto Backup and Delete old Backup# Date:2017-8-19source /etc/profilebackupdir=/web/data/liuxx_bak   # 本地备份路径time=` date +%Y%m%d `date=` date +"%Y-%m-%d %H:%M:%S" `day=15  #本地备份保留天数# 数据库信息user=rootpassword=******host=127.0.0.1port=3306databases=wordpress# 本地网站根目录backhome=/web/data/html/if [ ! -d $backupdir ]; then  mkdir $backupdirfi        mysqldump -h $host -P $post -u $user -p$password ${data} | gzip > $backupdir/${data}_$time.sql.gzif [ "$?" == 0 ];then        echo "[${date}] 数据库 ${data} 备份成功!!" >> ${backupdir}/mysqllog.logelse#备份失败则进行以下操作        echo "[${date}] 数据库 ${data} 备份失败!!" >> ${backupdir}/mysqllog.logfi# 备份网站tar -zcvf $backupdir/liuxx_${time}.tar.gz $backhome > /dev/null 2>&1# 删除同步find $backupdir -name "*.gz" -type f -mtime +${day} -exec rm {} \; > /dev/null 2>&1先森将以上代码保存为‘liuxxbak.sh’,名称可以随意自定义。保存后需要增加可执行权限:chmod +x liuxxbak.sh使用说明:将以上内容变量按需修改:backupdir=本地备份绝对路径day=本地备份保留天数user=数据库用户名(建议使用root用户,出错可能性小)password=数据库密码host=数据库IP或域名port=数据库端口databases=数据库名称backhome=本地网站根目录脚本执行方式:./liuxxbak.sh或者/web/data/liuxxbak.sh    # 绝对路径执行如此可以检查一下是否能够成功备份。二、远程备份到七牛云储存1.命令。首先下载qshell命令行工具,下载页面:根据服务器类型选择下载linux 64位的服务器可以直接在服务器上这样下载并增加可执行权限:wget -O qshell http://devtools.qiniu.com/2.1.3/qshell-linux-x64 && chmod +x qshell可以将qshell命令放入自定义目录。或直接放至/usr/bin/路径下,这样就可以任何地方直接输入命令了。2.鉴权。有了命令之后,我们需要七牛的鉴权,否则没法使用接下来的命令。需要鉴权的命令都需要依赖七牛账号下的 AccessKey 和 SecretKey。所以这类命令运行之前,需要使用 account 命令来设置下 AccessKey ,SecretKey 。鉴权的方式很简单,首先进入七牛的个人中心->密钥管理中,找到AccessKey 和 SecretKey。然后在服务器中运行一下命令:/web/data/qshell account ak sk执行之后,用户的所有信息写入到磁盘$HOME_DIR/.qshell下面。如:root用户执行后,信息会保存在/root/.qshell/account.json文件中。如果你修改了密钥,只需要重新执行以上命令即可,配置信息将被覆盖。3.同步。终于到了这一步。qshell命令的命令有很多,同步需要用到的命令是qupload。qupload是用来将本地目录中的文件同步到七牛空间中的命令。命令格式:qshell qupload [<ThreadCount>] <LocalUploadConfig>ThreadCount:并发上传的协程数量,默认为1,即文件一个个上传,对于大量小文件来说,可以通过提高该参数值来提升同步速度。LocalUploadConfig:数据同步的配置文件,该配置文件里面包含了一些诸如本地同步目录,目标空间名称等信息。ThreadCount是可以忽略的参数,默认一个文件一个文件的上传,因为是要备份数据库和本地网站文件,文件较少且大,顾保持默认就好。LocalUploadConfig为配置文件,配置文件中可带的参数共有21个,先森选用了其中的7个。详细的配置介绍请看这里。先森选用的参数如下,将以下内容保存到文件‘localupload.cnf’:{   "src_dir"            :   "/web/data/liuxx_bak",   "bucket"             :   "liuxx-backup",   "ignore_dir"         :   true,   "overwrite"          :   true,   "check_exists"       :   true,   "check_hash"         :   true,   "rescan_local"       :   true}解释,*为必须项:"src_dir":"/web/data/liuxx_bak",  # 本地备份路径*"bucket":"liuxx-backup",    #同步数据的目标空间名称,可以为公开空间或私有空间*"ignore_dir":true,    #远程同步到七牛时,忽略本地路径"overwrite":true,    #覆盖同名文件"check_exists":true,    #上传前检查是否有同名文件"check_hash":true,    #在check_exists设置为true的情况下生效,是否检查本地文件hash和空间文件hash一致"rescan_local":true,    #检测本地新增文件并同步最后,远程同步到七牛云储存的命令为:/web/data/qshell qupload /web/data/localupload.cnf可以执行一下上面的命令,检查是否能够成功同步。先森同步到七牛云的效果:同步效果三、定时备份同步准备工作已经完毕了,现在所需的就是每天的自动备份及远程备份了。执行crontab -e添加以下内容:00 02 * * * /web/data/liuxxbak.sh30 02 * * * /web/data/qshell qupload /web/data/localupload.cnf >/dev/null 2>&1凌晨两点执行本地备份,凌晨两点半执行远程备份。当然,你也可以将qshell命令加到liuxxbak.sh脚本的最后,那么只用添加第一条计划任务就可以了。四、七牛十五天循环备份七牛云储存免费的存储空间大小是10G,如果你的七牛云存储空间有点紧急的话,可以继续本操作。这时候,点击‘生命周期’,添加规则,我们可以设定删除15天前的文件。先森设定的规则如下:删除15天前的文件当然,如果七牛云存储的剩余空间很足的话,可以保留更多天,这样可供回退的版本就更多了。总结无论是用虚拟主机,还是使用云服务器,有一套备份的机制是很重要的。如果像先森一样,主站使用的是虚拟主机,也有另外的云服务器的话,这套备份方案改改,也可以把自己虚拟主机的数据库一起备份起来嘛。

七牛图片处理样式的正确使用方式

经验杂笔七牛图片处理样式的正确使用方式

标签:, | 11 条评论 | 2016-09-15

七牛图片处理样式,也就是我们通过创建一个样式,样式内定义了要对图片进行怎样的操作,然后我们只需要在图片后面加上样式分隔符和样式名称,即可对图片进行处理的一种方式。说起来,这种方式就像我们添加在functions.php中定义的加在钩子上的函数,要用的时候,直接调用函数,函数内的处理也就随之而动了。使用方法七牛图片处理样式,之前先森一直称其为七牛裁剪代码。因为先森将处理样式用在的一般是缩略图上,所以称之为裁剪;而代码主要就是先森闹了笑话了。先森之前对七牛图片处理样式的使用一直是将样式内容直接加在图片后面,中间加上了个问号,这样就导致图片的链接看起来非常的长(如下图)。加上七牛裁剪代码链接特别显得长上面的这种使用方式,简而言之就是,七牛为我们准备好了一个调用函数,而先森却非要每次都把函数内容重新写一遍。还好,先森在@第9页看到了正确的使用方法。正确的使用方法应该如下图,直接用斜杠+样式名称。正确的使用方式注意事项1.七牛图片处理样式的个数不是固定的,每个存储空间可以定义100个图片处理样式。这一点对我们小站影响比较小,先森目前才使用7个样式。2.就像PHP语言要加上<?php ?>来区分php代码一样,图片链接那么长,图片名称和图片处理样式的名称都是用户自定义的,万一两个名称重复了怎么办呢?所以,七牛也需要一个协议好的“定义”来区分一串字符是否为图片处理样式。而七牛的这个“定义”,就是样式分隔符。样式分隔符这个样式分隔符乍眼一看,好像没有什么作用,选择哪一个好像都没有什么。但是,先森使用之后,认为这个分割符还是很有作用的。样式分隔符能够使用的符号如下:- _ ! / ~ ` @ $ ^ & * ( ) + = { } [ ] | : ; " ' < > , .七牛默认使用的是斜杠,但先森觉得,这个斜杠就是最不应该作为样式分隔符的。先森使用斜杠为分隔符之后,网站上的图片名称就完全一样了。道理很简单,在一个链接中,最后一个斜杠后面的内容,默认为下载后的文件名。如下图,dengxiang是先森设置的样式名,清一色啊。文章中的图片全是图片样式名称所以先森也会找时间,把七牛的图片样式分隔符,以及主题中的样式分隔代码给更换了。大家可以看看七牛官方的演示图片,以中横线为样式分隔符的效果:以中横线为分隔符的效果所以希望还没有开始使用七牛图片处理样式的朋友,第一步先更改样式分隔符。代码部分如果使用七牛图片处理样式,就相当于修改了图片的后缀名,所以七牛云储存也就匹配不到文章中的图片了。在使用斜杠为分隔符的情况下,先森尝试了修改七牛云储存中的本地设置-扩展名设置(因为分隔样式是斜杠,所以用了反斜杠转移,不然会出错),但是并没有起作用。大家可以试试换了分隔符后的情况。扩展名修改所以,只能摒弃七牛云储存了。然后我们需要做的是将图片拉取到七牛存储空间,然后网站上访问的也是来着七牛的图片。因为从一开始先森使用的就是七牛云储存,而七牛云储存设置的第一步就是填写API,这让先森陷入了一个误区——没有API图片就不会保存到七牛存储空间。后来先森想明白了,只需要直接把图片上的域名改为七牛的域名,然后七牛会判断图片是否存在于存储空间。如果存在,直接输出;如果不存在,回源拉取图片到七牛存储空间。那么明白了就简单了,我们只需要将网站上图片链接中的域名直接换成七牛域名即可,在主题的functions.php中添加://WordPress七牛CDN代码版function QiNiuCDN(){    function Rewrite_URI($html){        /* 前面是需要用到七牛的域名,后面是需要加速的静态文件类型,使用分隔符 | 隔开即可 */        $pattern ='/http:\/\/(www\.|)capjsj\.cn\/(wp-|ueditor|avatar)([^"\']*?)\.(jpg|js|css|gif|png|jpeg)/i';        /* 七牛CDN空间地址,请自行替换成实际空间地址 */        $replacement = 'http://img.capjsj.cn/$2$3.$4';    $html = preg_replace($pattern, $replacement,$html);    return $html;    }    if(!is_admin()){        ob_start("Rewrite_URI");    }}add_action('init', 'QiNiuCDN');这样我们就用代码实现了将静态资源拉取到七牛存储空间。接下来需要做的,是给文章中的图片加上七牛蹄片处理样式,同样是在functions.php中添加:/** * 七牛缩略图和水印 D9Y.NET整理**/function QiNiuThumbnailWatermark($content) {   global $post;   $pattern ="/<img(.*?)src=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>/i";   /* 下面这行代码中的dengxiang是七牛样式中的样式名称,而斜杠为七牛中设置的样式分割符 */   $replacement = '<img$1src=$2$3.$4/dengxiang$5$6>';   $content = preg_replace($pattern, $replacement, $content);   return $content;}add_filter('the_content', 'QiNiuThumbnailWatermark');?>当然,上面这串代码只是一下就将网站文章图片添加上了七牛图片处理样式,其他如相关文章、最新文章、文章列表中的缩略图还没有添加对应的样式。对于这些,先森是直接在调用图片时手动添加样式,直接加在functions.php中的函数,先森还没去研究。先森的例子如下:<img src="<?php echo post_thumbnail_src(); ?>/sidebar" alt="<?php the_title(); ?>" />总结总之,使用七牛图片处理样式,能使你的图片链接看上去更清爽。但如果使用斜杠为样式分隔符,又会使你的图片名称看起来非常操蛋。另外,七牛图片处理,不仅仅是裁剪图片大小,更为重要的是,可以设置图片水印。

用cookie记住用户信息后ajax实现实时显示Gravatar头像并实时缓存到本地

经验杂笔用cookie记住用户信息后ajax实现实时显示Gravatar头像并实时缓存到本地

标签:, , | 7 条评论 | 2016-04-18

首先说一点,本文的内容是先森研究了几天的成果,并且还导致了网站几天没有更新。先森之前遇到了开启CDN后网站会连先森登录之后的显示样式一起缓存的问题。想想还是很危险的,要是文章页第一次是被已知用户访问,那么其他所有人访问后就是他看到的样子,那样说不定连他的邮箱地址都被暴露了。这个问题很容易解决,通过张戈博客的cookie记住用户信息的方法,再加上让所有人访问网站都是未登录状态,这个问题就OK了。再加上一些优化用户体验的操作,也没有花先森多少时间,但是gravatar头像的事情,却一直横在了先森心中,先森的强迫症就又犯了。关于过往研究的历程,先森已经分享过了,如果没有看的最好可以去看看,本文是建在之前的基础之上的:用cookie解决网站开启CDN缓存之后已知用户头像昵称被缓存等系列问题用cookie记住用户信息后隐藏信息输入框,优化用户体验预期效果先森想实现的显示Gravatar的方式,并不是简单的用多说或者Gravatar中国的服务器的那种。先森之前就用的是将头像本地缓存,用以提高加载速度。所以先森想实现的是:1.用户是已知用户的时候,页面打开时自动加载缓存在本地服务器的其邮箱对应的Gravatar头像。2.如果用户修改或填写邮箱的时候,则自动将其对应的Gravatar缓存到本地服务器,再显示出来。如果服务器不使用本地服务器的话,上面的两条很容易实现。因为不用缓存,而Gravatar的头像链接又是固定的http://www.gravatar.com/avatar/xxxx(xxxx为邮箱的md5加密值),只要获取到邮箱,将邮箱通过哈希算法变为md5加密值,将这段MD5值填入链接中,就是用户的头像了。但难就难在先森想要将头像同时本地缓存。不过,经过几天的努力,绕了很大的圈子,总算是搞定了。效果实现相信很多WordPress站长的评论源代码,是由comments.php、comments-ajax.php、comments-ajax.js三个文件构成。如果是则很会很方便,不是也没有多大差别。1.将Gravatar头像缓存到本地服务器这个教程早就已经烂大街了,为了本文内容先森不得不重提一遍。为什么要缓存到本地服务器?因为Gravatar是国外服务器的,很容易被墙,且容易访问超时,导致网页加载速度变慢。缓存到本地服务器就可以有效的解决这个尴尬。当然,你也可以直接把头像缓存到七牛云储存,也就没有本文这么麻烦了。为什么先森要选择麻烦的方法?爱折腾呗~将Gravatar头像缓存到本地服务器的方法就是,在你的functions.php中加入以下代码://本地缓存gravatar头像function fa_cache_avatar($avatar, $id_or_email, $size, $default, $alt){    $avatar = str_replace(array("www.gravatar.com", "0.gravatar.com", "1.gravatar.com", "2.gravatar.com"), "gravatar.duoshuo.com", $avatar);    $tmp = strpos($avatar, 'http');    $url = get_avatar_url( $id_or_email, $size ) ;    $url = str_replace(array("www.gravatar.com", "0.gravatar.com", "1.gravatar.com", "2.gravatar.com"), "gravatar.duoshuo.com", $url);    $avatar2x = get_avatar_url( $id_or_email, ( $size * 2 ) ) ;    $avatar2x = str_replace(array("www.gravatar.com", "0.gravatar.com", "1.gravatar.com", "2.gravatar.com"), "gravatar.duoshuo.com", $avatar2x);    $g = substr($avatar, $tmp, strpos($avatar, "'", $tmp) - $tmp);    $tmp = strpos($g, 'avatar/') + 7;    $f = substr($g, $tmp, strpos($g, "?", $tmp) - $tmp);    $w = home_url();    $e = ABSPATH .'avatar/'. $size . '*'. $f .'.jpg';    $e2x = ABSPATH .'avatar/'. ( $size * 2 ) . '*'. $f .'.jpg';    $t = 1209600; //缓存更新时间    if ( (!is_file($e) || (time() - filemtime($e)) > $t) && (!is_file($e2x) || (time() - filemtime($e2x)) > $t ) ) {         copy(htmlspecialchars_decode($g), $e);        copy(htmlspecialchars_decode($avatar2x), $e2x);    } else { $avatar = $w.'/avatar/'. $size . '*'.$f.'.jpg';        $avatar2x = $w.'/avatar/'. ( $size * 2) . '*'.$f.'.jpg';        if (filesize($e) < 1000) copy($w.'/avatar/default.jpg', $e);        if (filesize($e2x) < 1000) copy($w.'/avatar/default.jpg', $e2x);        $avatar = "<img alt='{$alt}' src='{$avatar}' srcset='{$avatar2x}' class='avatar avatar-{$size} photo'  id='real-time-gravatar' height='{$size}' width='{$size}' />";    }    return $avatar;}add_filter('get_avatar', 'fa_cache_avatar',1,5);如果你的网站已经实现则忽略,没有的话就先添加备用。2.新建gravatar.php上面的代码是修改了WordPress的get_acatar函数。而我们想要实时的缓存Gravatar邮箱,则需要将邮箱的MD5值传递给get_acatar函数。上面的代码最后会有输出,而我们并不需要它的输出,只要它将头像缓存即可。所以我们需要新建一个gravatar.php文件,将ajax传递过来的邮箱MD5值接收,并让get_acatar函数将对应的头像缓存。gravatar.php的代码如下:<?php //缓存头像if ( 'POST' != $_SERVER['REQUEST_METHOD'] ) { header('Allow: POST'); header('HTTP/1.1 405 Method Not Allowed'); header('Content-Type: text/plain'); echo "请不要直接访问该页面"; exit;}require( dirname(__FILE__) . '/../../../wp-load.php' );//使用 WordPress自带函数进行数据提交 $email = $_POST['email'];//获取邮箱md5值 get_avatar( $email, $size = '48' ); //将头像缓存 ?>其中,下面这段代码很重要:require( dirname(__FILE__) . '/../../../wp-load.php' );如果不加上的话会导致数据存入失败,POST访问也会返回错误500。这也是挡住了先森研究很久的一个问题。之前代码中之后最后的两句,获取和缓存,结果一直显示不成功。访问错误500后来在百度找原因一直没找到,却意外看到了一篇写用ajax提交评论的优点的文章中有一句“使用wordpress自带的admin-ajax.php进行数据提交”,先森感觉脑子一炸,将comments-ajax.php中一句不起眼的代码(即上面那句)复制过来。一尝试。OK返回成功。3.ajax动态刷新ajax是一种在不刷新整个页面,与服务器实现数据交换的网页开发技术。这个技术被称为称为“艺术”,但先森是不懂艺术的,所以这几天花的最多的时间就是在这里了。先森还专门跑去w3school学了一下ajax方面的教程,结果也没懂个啥,仅仅是对概念更清楚了些。这个技术在本文的担当是,动态的将邮箱md5值提交给服务器,服务器将头像缓存。我们的ajax代码,可以加入到comments-ajax.js中,也可以自己新建一个js文件。首先,我们需要将Gravater邮箱地址变换为MD5值,需要用到一串复杂的算法,将以下代码加入js中:Gravatar头像邮箱转MD5下载因为比较长,所以提供下载,不直接将代码贴出来了。接下来将下面的代码加入comments-ajax.js或你准备好的js文件中:/**张戈博客原创*成航先森修改* http://www.capjsj.cn/ycookiejzyhxxhsxssxsgravatartxbsshcdbd.html ‎*/var Umail = decodeURIComponent(GetCookie('email'));//通过cookie获取用户邮箱,并解码var Uname = decodeURIComponent(GetCookie('author'));var Umail_md5 = "";if (Umail != "null" && Umail != "" && Umail != null) {//如果邮箱有内容,则赋值 var Umail_md5 = hex_md5(Umail);}if (Umail_md5 != "" && Umail_md5 != null && Umail_md5 != "null") {//如果邮箱哈希后存在内容 jQuery(document).ready(function($) { jQuery('#comment-author-info').hide();//隐藏信息填写框 }); /*下面的real-avatar是包裹着头像的div*/ document.getElementById('real-avatar').innerHTML = "<img src='http://img.capjsj.cn/avatar/96*" + Umail_md5 + ".jpg' width='48' height='48' alt='avatar' class='avatar avatar-48 photo' id='real-time-gravatar'>"; var changeMsg = '修改信息'; var closeMsg = '关闭'; function toggleCommentAuthorInfo() { jQuery('#comment-author-info').slideToggle('slow', function() { if (jQuery('#comment-author-info').css('display') == 'none') {//如果信息填写框被隐藏 jQuery('.switch-author').text(changeMsg);//改变标签内容为“修改信息” } else { jQuery('.switch-author').text(closeMsg);//改变标签内容为"关闭" } }); }}var gar_img = document.getElementById("real-time-gravatar");/*头像img标签*/var U_email = document.getElementById("email");var textarea = document.getElementById("comment");/*评论输入框*/var KaK = navigator.userAgent.toLowerCase();/*获取浏览器信息*/var chrome = KaK.indexOf('webkit') != -1;function changeGravatar() { email_value = U_email.value; email_md5 = hex_md5(email_value); php_url=js_url.replace('comments-ajax.js','gravatar.php');//替换js链接中的文件名 $.ajax({        type:'POST',        data:{            "email": email_value,            },        //ajax对象文件:gavater.php        url:php_url,        cache: false,    });  new_ga = "http://img.capjsj.cn/avatar/48*" + email_md5 +".jpg"; newGravatar(new_ga);/*启动下面的脚本*/};function newGravatar(new_ga) { gar_img.setAttribute('src', new_ga);/*将图片链接换成新的链接*/};if (chrome) { U_email.onblur = changeGravatar;/*鼠标离开输入框时执行 JavaScript 代码*/} else { U_email.onchange = changeGravatar;/*在内容改变的时候执行*/};textarea.onmouseover = changeGravatar;/*在鼠标指针移动到元素上时触发行 JavaScript 代码代码是从张戈博客那里扒来的,因为张戈实现的是Nginx自动将Gravatar头像本地缓存,所以他不用担心先森的这种缓存问题。所以先森将张哥的代码稍作修改,增加了ajax代码,既可以满足先森的要求了。上面的代码中,ajax代码是下面这串:$.ajax({        type:'POST',        data:{            "email": email_value,            },        //ajax对象文件:gavater.php        url:php_url,        cache: false,    });如果你需要调试,可以将代码缓存下面这样,根据弹窗信息确认是否成功: $.ajax({        type:'POST',        data:{            "email": email_value,            },        //ajax对象文件:gavater.php        url:php_url,        cache: false,  error: function(){             alert('发生意外错误!'); //弹窗显示            return false;         },         success:function(){            alert('缓存成功');        }    });应网友要求,先贴出comments.php中form标签的内容,以供参考。 <form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform"> <div class="comt-title" id="comt-title"> <div class="comt-avatar pull-left" id="real-avatar"> <?php //输入评论上的头像 global $current_user; get_currentuserinfo(); if ( is_user_logged_in() ) //$current_user->user_email获取邮箱 echo get_avatar( $current_user->user_email, $size = '48' ,'');//如果是管理员 elseif( !is_user_logged_in() && get_option('require_name_email') && $comment_author_email=='' )  echo get_avatar( $current_user->user_email, $size = '48','');//没有登录,但是是已知用户 elseif( !is_user_logged_in() && get_option('require_name_email') && $comment_author_email!=='' )   echo get_avatar( $comment->comment_author_email, $size = '48','');//, $touxiang  else echo get_avatar( $comment->comment_author_email, $size = '48' ,'');//, $touxiang  ?> </div> <div class="comt-author" id="switch-author"> <?php  if ( is_user_logged_in() ) {//判断登录 printf('<b id="nickname">'.$user_identity.'</b><span>发表我的评论</span>'); }else{ if( get_option('require_name_email') && !empty($comment_author_email) ){//如果没登录,但是是已知用户 printf('<b id="nickname">'.$comment_author.'</b><span>欢迎回来</span> &nbsp;<b>【<a class="switch-author" href="javascript:toggleCommentAuthorInfo();" data-type="switch-author" style="font-size:15px;">修改信息</a>】</b>'); }else{//如果是未知用户 printf('<b id="nickname"></b><span id="huilai">欢迎发表评论</span>'); } } ?>            <?php //如果关闭了WP Super Cache中的让已知用户匿名,则要删除下面的<b>标签?>            <b id="switch-author" style="display:none">【<a class="switch-author" href="javascript:;" data-type="switch-author" style="font-size:15px;">修改信息</a>】</b>            </div> <a id="cancel-comment-reply-link" class="pull-right" href="javascript:;">取消评论</a> </div> <div class="comt"> <div class="comt-box"> <textarea placeholder="说点什么吧,您的回复是对先森最大的支持!" class="input-block-level comt-area" name="comment" id="comment" cols="50%" rows="3" tabindex="1" onkeydown="if(event.ctrlKey&amp;&amp;event.keyCode==13){document.getElementById('submit').click();return false};"></textarea> <div class="comt-ctrl"> <button class="btn btn-primary pull-right" type="submit" name="submit" id="submit" tabindex="5"><i class="fa fa-check-square-o"></i> 提交评论</button> <div class="comt-tips pull-right"><?php comment_id_fields(); do_action('comment_form', $post->ID); ?></div>                    <span class="muted comt-mailme"><?php deel_add_checkbox() ?></span> <span data-type="comment-insert-smilie" class="muted comt-smilie"><i class="fa fa-smile-o"></i> 表情</span>                                        <div id="comment-smilies" class="hide" style="display:"><?php include(TEMPLATEPATH . '/smiley.php'); ?></div> </div> </div> <?php if ( !is_user_logged_in() ) { ?> <?php if( get_option('require_name_email') ){ ?> <div class="comt-comterinfo" id="comment-author-info"<?php if ( !empty($comment_author) ) echo 'style="display:none"';else echo 'style="display:block"'; ?>> <h4>Hi,您需要填写昵称和邮箱!</h4> <ul> <li class="form-inline"><label class="hide" for="author">昵称</label><input class="ipt" type="text" name="author" id="author" value="<?php echo esc_attr($comment_author); ?>" tabindex="2" placeholder="昵称"><span class="help-inline">昵称 (必填)</span></li> <li class="form-inline"><label class="hide" for="email">邮箱</label><input class="ipt" type="text" name="email" id="email" value="<?php echo esc_attr($comment_author_email); ?>" tabindex="3" placeholder="邮箱"><span class="help-inline">邮箱 (必填)</span></li> <li class="form-inline"><label class="hide" for="url">网址</label><input class="ipt" type="text" name="url" id="url" value="<?php echo esc_attr($comment_author_url); ?>" tabindex="4" placeholder="网址"><span class="help-inline">网址</span></li> </ul> </div> <?php } ?> <?php } ?> </div> </form>总结文中的代码涉及到了很多标签的ID,请参考本站的设置情况进行对应修改。因为代码逐行执行的速度比服务器缓存的速度快,所以当刚修改邮箱的时候,可能图片会显示404,但再次触发更换头像链接函数的时候,相关的头像已经被缓存成功就会显示出来了。先森目前没有想到解决的办法,所以最后有一个经过评论输入框的时候也会触发函数。这样增加触发,头像就能很好的显示出来了,目前先这样,等以后想到解决办法再说。这样设置后的好处还有一点,就是默认头像始终都是你设置本地缓存中的那个默认头像。

用cookie记住用户信息后隐藏信息输入框,优化用户体验

经验杂笔用cookie记住用户信息后隐藏信息输入框,优化用户体验

标签:, , | 1条评论 | 2016-04-17

上一篇文章,先森解决了设置CDN缓存后,用户信息无法被记住的问题。使用的是JS代码操作cookie,用cookie记住用户信息,这样就可以无视缓存了。但这解决的只是初步的技术难题,后续我们还需要对用户体验做好优化。先森是这样想的,当cookie中,保存了用户有效信息后,起码要做到这几点:1.昵称、邮箱、网址的填写框就应该自动隐藏。2.头像旁边显示用户昵称。3.同时,还需要在旁边增加一个按钮,方便用户修改信息。隐藏信息填写框其实很简单,我们只需要在读取cookie信息并写入填写框之后,添加一段代码即可。关于用cookie保存用户信息的全部代码,大家请看前篇文章:用cookie解决网站开启CDN缓存之后已知用户头像昵称被缓存等系列问题我们在“加载用户信息”那一段中添加代码。你们可以把前文中的“加载用户信息”部分的代码换成下面这段(主要是19行)://加载用户信息function LoadRememberInfo() { var strName=GetCookie("author"); var strEmail=GetCookie("email"); var strHomePage=GetCookie("url"); var bolRemember=GetCookie("chkRemember");    var a_vlaue= document.getElementById("author");    if (a_vlaue != null){     if(bolRemember=="true"){ //如果勾选了“记住我”                    //通过decodeURIComponent对内容解码     if(strName){document.getElementById("author").value=decodeURIComponent(strName);//从 cookie获取填写昵称 };     if(strEmail){document.getElementById("email").value=strEmail;};//从 cookie获取填写邮箱                     //通过decodeURIComponent对内容解码     if(strHomePage){document.getElementById("url").value=decodeURIComponent(strHomePage);};//从 cookie获取填写网址     if(bolRemember){document.getElementById("saveme").checked=bolRemember;};//----------------新增代码-开始--------------------- document.getElementById("comment-author-info").style.display="none";//隐藏“需要填写昵称邮箱” document.getElementById("nickname").innerHTML=document.getElementById("author").value;//让头像旁边,显示已知用户的名称 document.getElementById("huilai").innerHTML='欢迎回来';//将“欢迎发表评论”改为“欢迎回来” document.getElementById("switch-author").style.display="";//显示“修改信息”//----------------新增代码-结束---------------------     }     if(GetCookie("username")){     document.getElementById("author").value=unescape(GetCookie("username"));     }    } }主要是上面新增代码部分,后面的注解写的很清楚了,请根据自己的实情修改。

用cookie解决网站开启CDN缓存之后已知用户头像昵称被缓存等系列问题

经验杂笔用cookie解决网站开启CDN缓存之后已知用户头像昵称被缓存等系列问题

标签:, , | 2 条评论 | 2016-04-17

先森之前也提到过,CDN开启网页HTML缓存之后,一篇文章在没有缓存的情况下,如果第一次访问是先森自己访问的(或者是其他已知访客访问的),那CDN缓存的时候,就会把先森登录后显示的界面缓存下来。先森自己的头像被缓存也就是其他访客访问的时候,会显示“内容管理”、“登出”、评论框会显示先森的头像,前面两个因为没有登录,所以点击之后也没有用,但是评论框显示先森的头像的时候,没有更改昵称和邮箱的选项,当访客写好评论提交的时候会提示“请输入昵称和邮箱”。虽然可以修改PHP代码,让昵称和邮编填写框都显示出来,但是这样是逃避问题,治标不治本。免费资源部落的博主提醒先森,可能是开了浏览器缓存的问题。但是先森看了百度云加速的缓存设置,浏览器缓存最低设置时间都是两个小时,没有关闭浏览器缓存的选项。而且,先森仔细想了一下,觉得也不可能是浏览器缓存的问题,先森的问题是当先森自己访问后一篇文章后,别人在自己的电脑上再访问同样的网页后,会显示和先森一样的界面。而浏览器缓存,只会存在自己的电脑上。解决问题在网上搜索了半天解决方法都没有找到类似的教程,最后终于在张戈博客找到了很适合的解决方案。就是用cookie来记住已知用户,摒弃WordPress本身的记住用户。先森的想法是:1.WordPress方面。用WP Super Cache设置访客访问到的页面样式。用之前介绍过的两个设置“不要为已知用户缓存”和“让已知用户匿名使他们浏览的内容是缓存文件”来使所有访客访问到的页面都相同,并且不增加服务器的负担。WP Super Cache的两个设置2.CDN方面。通过了第一步的设置,CDN再设置缓存除后台外的所有内容,则不会再出现缓存到已知用户头像和昵称的问题了。因为就算是站长登录,网页中显示的也是未登录的状态。3.JS方面。通过上面两步设置之后,即使是以前在网站评论过的小伙伴,每次评论也都需要重新填写昵称和邮箱,这样对用户体验不好,所以我们就要使用上文提到的将已知用户信息存在用户自己的设备cookie中,每次进入网站,会自动从cookie读取填写信息,这样就不用劳烦已知用户们自己填写了。当然,昵称邮箱这些并不是私密等级非常高的信息,我们没必要用session了。WordPress的WP Super Cache设置和CDN的设置很简单,需要注意的是缓存的时间,这个根据自己网站来设定。关键的是JS代码布置的问题。张戈为我们分享了他的代码,前后共有两篇文章,前篇是旧的代码分享及如何布置,后篇是改良之后的代码分享:WordPress记住评论用户信息的js版本,直接操作cookie无视缓存解决JS操作Cookies出现的乱码问题,修复WordPress评论乱码先森以为布置起来会很麻烦,但是经过实践后发现,布置起来还是很快的,只要你和张戈一样,使用的是原生的WordPress评论。部署代码很简单,将下面的代码加入主题的comments-ajax.js中,或者其他js里面:/**WordPress记住评论用户信息的js版本,直接操作cookie无视缓存*https://zhangge.net/4538.html*https://zhangge.net/4684.html*///设置Cookiefunction SetCookie(sName, sValue,iExpireDays) { if (iExpireDays){ var dExpire = new Date(); dExpire.setTime(dExpire.getTime()+parseInt(iExpireDays*24*60*60*1000)); document.cookie = sName + "=" + escape(sValue) + "; expires=" + dExpire.toGMTString()+ "; path=/;domain=.capjsj.cn"; } else{ document.cookie = sName + "=" + escape(sValue)+ "; path=/;domain=.capjsj.cn"; }}// 目的:    返回Cookiefunction GetCookie(sName) { var arr = document.cookie.match(new RegExp("(^| )"+sName+"=([^;]*)(;|$)")); if(arr !=null){return unescape(arr[2])}; return null; }//加载用户信息function LoadRememberInfo() { var strName=GetCookie("author"); var strEmail=GetCookie("email"); var strHomePage=GetCookie("url"); var bolRemember=GetCookie("chkRemember");    var a_vlaue= document.getElementById("author");    if (a_vlaue != null){     if(bolRemember=="true"){ //如果勾选了“记住我”                    //通过decodeURIComponent对内容解码     if(strName){document.getElementById("author").value=decodeURIComponent(strName);//从 cookie获取填写昵称 };     if(strEmail){document.getElementById("email").value=strEmail;};//从 cookie获取填写邮箱                     //通过decodeURIComponent对内容解码     if(strHomePage){document.getElementById("url").value=decodeURIComponent(strHomePage);};//从 cookie获取填写网址     if(bolRemember){document.getElementById("saveme").checked=bolRemember;};     }     if(GetCookie("username")){     document.getElementById("author").value=unescape(GetCookie("username"));     }    } }//通过jQuery ready在页面加载时自动从cookies中载入已保存的用户信息jQuery(document).ready(function($){       LoadRememberInfo();//给评论提交按钮绑定信息保存函数    $("#respond #submit").click(function(){       SaveRememberInfo();    });//给评论重置按钮绑定信息移除函数    $("#respond #reset").click(function(){        RemoveRememberInfo();    });});//保存信息函数function SaveRememberInfo() { var strName=document.getElementById("author").value; var strEmail=document.getElementById("email").value; var strHomePage=document.getElementById("url").value; var bolRemember=document.getElementById("saveme").checked;        //通过encodeURIComponent对内容进行url编码 SetCookie("author",encodeURIComponent(strName),365); SetCookie("email",strEmail,365);        //通过encodeURIComponent对内容进行url编码 SetCookie("url",encodeURIComponent(strHomePage),365); SetCookie("chkRemember",bolRemember,365); }//移除信息函数function RemoveRememberInfo() { SetCookie("author",'',365); SetCookie("email",'',365); SetCookie("url",'',365); SetCookie("chkRemember",'false',365);}当然上面的代码还是要根据你自己主题设置的标签ID来更改。新的问题但是布置好之后,先森却遇到了麻烦。cookie可以记录邮箱和网址的信息,却死活记录不了昵称的信息。在网页cookie中看到,author的信息显示的是undefined(未定义)。昵称author显示undefined先森前前后后折腾了几个小时,百度各种搜索,甚至还在张戈博客留言问张哥。最后还是显示在凌晨1点多,想要放弃的时候,发生了转机。先森之前测试cookie的时候,只填写了昵称和邮箱,但是昵称author始终显示undefined,而网址一栏的cookie显示的是空值。开始先森没有在意,后来一想,如果昵称是没有获取到值的话,为什么不是和网址一样,显示的是空值呢?这样一想就醒悟了,应该是标签的ID存在冲突了。果然,先森发现,文章页中,标题下的编辑的<span>标签,也用的author标签。标签ID重复把标签的ID换了,删除缓存,刷新查看。果然,该缓存的都缓存了。另外,下图中的comment_author_****的三行代码,是WordPress比较通用的comments-ajax.php中添加的,其实使用这种方法之后,这些cookie就可以删掉了。但是先森觉得有点麻烦,还没钻研透,也就还没删。等以后钻研透了再删除,毕竟cookie信息也会影响网页打开速度。cookie测试成功删改代码经过这样一番整改之后,网站前端在设计的时候,增加的一些判断管理员登录的代码都失效了,所以这类内容就可以删除了。功能-登录-管理网站先森网站上比较突出的,就是登录之后的管理按钮,这些都可以直接删除了。<?php if ( function_exists('dynamic_sidebar') && dynamic_sidebar() ) : else : ?>            <p  class="categoryName1"><?php _e('Meta'); ?></p>            <img src="<?php bloginfo('template_url'); ?>/images/news_fenge2.jpg" alt="分段图" title="分段图"><ul class="categoryName2 login_ul"><?php wp_register(); ?><li><?php wp_loginout(); ?></li><?php wp_meta(); ?></ul>    <?php endif; ?>总结用cookie的方式记录访客信息,访客信息会放在访客自己的设备上,只要访客自身不禁用cookie,就没有什么问题。经过本文的设置之后,gavater头像就不能实时显示了。当然,也有解决办法,实时显示gavater头像的教程很多。但先森不满足,因为之前先森的gavater头像都缓存到了自身服务器,先森不想使用多说等其他服务器。先森目前已经实现了实时将访客输入的邮箱对应的gavater头像缓存到自身服务器,并显示出来,相关教程如下:用cookie记住用户信息后ajax实现实时显示Gravatar头像并实时缓存到本地用cookie记住用户信息后隐藏信息输入框,优化用户体验cookie保存信息失败,要检查是否是因为标签的ID冲突原因。

全站CDN缓存加速之接入百度云加速

经验杂笔全站CDN缓存加速之接入百度云加速

标签:, , | 6 条评论 | 2016-04-12

先森现在待业,时间比较多,所以折腾网站的时间就比较多了。成航先森已经接入过腾讯云、VeryCloud两家的全站CDN了,接入经过也跟大家分享了。而现在,先森又将网站接入到百度云加速了。虽然接入时间不长,但是先森还是将自己汲取到的经验赶紧分享出来,不然自己都忘了就不好了。百度云加速关于接入腾讯云、VeryCloud的经历,有兴趣的童鞋可以去看看:全站CDN缓存加速之接入腾讯云全站CDN缓存加速之接入VeryCloud接入百度云加速先森之前CDN的默认解析使用的是VeryCloud,电信线路解析的是腾讯云。使用了一段时间,先森发现电信线路下,网站经常莫名的打不开:同一个WIFI网络下,电脑打不开,手机却正常;手机不能打开内容页,电脑却正常等等各种奇葩问题。还有就是联通线路下,网页再怎么刷新,响应头中还是显示的MISS,没有命中缓存,虽然Linux中通过命令查看可以HIT,但是先森是强迫症的嘛,心里总是有个疙瘩。综上所述,再加上想鼓捣一下百度云,所以就跟换到百度云加速了。怎样接入百度云加速,网上的教程一大堆,先森就不再赘述了。WordPress嘛,使用CDN主要的一点,就是不能把后台也给缓存进去了。我们要使用百度云加速的规则自定义,设置缓存和不缓存的内容。百度云加速免费版只能设置3条规则,各位小伙伴要根据实情设置。先森要求不高,暂时3条完全够用。规则自定义-百度云加速根据张戈博客张哥的建议,先森这里只设置了网站后台细致缓存,其他全缓存(细致缓存其实就是只缓存静态文件)。百度云加速经验归纳1.免费版国内线路不包括移动百度云加速设置有免费版和专业版。CDN节点免费版不提供移动节点,也就是移动网络访问你的网站,将会从电信、联通等其他服务器获取数据。免费版与专业版的区别-百度云加速对于这个问题,先森的解决办法是单独设置移动解析线路,解析到腾讯云。要怎么解决这个问题,或者解析到什么CDN服务商,大家就根据自己的喜好来了。2.查看回源与命中缓存先森提交工单问客服,百度云加速给网站响应头加入哪些信息,又分别是什么意思,尤其是怎么查看是否命中缓存。其实先森自己心中已经有了猜测,只是想找客服证实一下。工单客服竟然说,Request Method(请求的方法)是GET则命中缓存。可爱的客服还截了本站的图,将GET部分给我看。最后把这位客服虐了一遍,他让我第二天上班时间找QQ在线客服(4008768800)。先森问了在线客服,了解到实际上重点需要关注的信息有两个:CF-Cache-Status:HITCF-RAY:291d911c1d5d1cc5-CTUCF-Cache-Status的话,HIT表示命中缓存,MISS表示回源。CF-RAY是查看通过什么节点访问的,这里表示的是通过成都节点访问的。至于如何来查看是通过是什么节点访问,客服说有需要可以询问他们,没有公开的查询方式。3.双重设置百度云加速中,规则自定义中设置规则里的选项,在网站通用设置中也有同样的选项设置,如浏览器检查、CC防护等设置。优先级是规则自定义大于通用设置。4.安全防护百度云能设置WAF等安全防护,小站表示会很放心。重点是这些是免费的。需要注意的是,不知道是WAF里的浏览器检查,还是ADS里的CC防护(或者是规则自定义里的CC防护),开启之后(CC防护设置为强力防护)会让如奇云测等网站检测工具的访问HTTP状态返回503。5.七牛访问源站响应超时,错误503不知道是真的只是当时源站响应超时还是百度云加速的问题,反正先森网站上新的图片不能访问,单独打开显示以下内容:{"error":"get from image source failed: E503"}先森的想法是:1.设置了浏览器检查的原因;2.WAF防护过猛,把七牛给防在外面了。先森觉得浏览器检查平时没什么用,访客首次打开还会显示5秒的浏览器检查页面,所以就把它关了。至于WAF防护,WAF可以设置白名单,先森赶紧发起七牛工单,将七牛的回源IP段添加到白名单中了。七牛给先森的回复如下,需要的童鞋也赶紧添加吧:镜像回源User Agent: qiniu-imgstg-spider-1.0镜像回源IP段 :183.136.139.0/24当然,百度云加速只能添加IP段,用户代理User Agent加在哪先森就不清楚了。不知道是哪个设置生效了,网站上的图片又能被七牛镜像缓存了。6.关闭了浏览器检查,但是访问网站还是经常有“浏览器检查中”的界面?浏览器检查,功能很好,对于明显不是浏览器的访问请求予以拒绝,以防止恶意抓取和垃圾信息。但是先森觉得对用户体验并不好。别人打开你的网站找教程,结果还要等5秒你的网站才开始加载,有几个会乖乖的等着的?百度云加速浏览器检查界面有时我们会发现,明明在设置中关闭了“浏览器检查”,但是打开的时候还是存在这个界面。第一种可能,上面也说过,你仅仅关闭了通用设置中的“浏览器检查”,在规则自定义中还有个一个“浏览器检查”的设置,而且这个设置的优先级还高于通用设置中的。第二种可能,你设置的CC防护的等级是“强力防护”,这个在规则自定义中也有设置,但是名字是“游览器检查”(先森向客服反馈,被证实为错字。客服已经反馈上去了,估计很快会修正)。客服告诉先森,设置CC防护等级为“高”,则不会再检查浏览器了。同时,设置为“高”的时候,再开启“浏览器检查”,用户访问也不会显示“浏览器安全检查中...”的字样。百度云加速CC防护7.没有日志与API接口百度云加速和VeryCloud、腾讯云不同的是,没有API,也没有日志。8.实时同步百度云加速可以打开实时同步,也就不做任何缓存,直接回源,这一点非常方便。总结用了两天的百度与云加速,感觉还是非常不错的。同一个页面,第一次访问显示MISS,刷新一下就显示HIT了,见效特别快,先森觉得特别痛快。虽说WordPress要多折腾,但是也确实很感谢如VeryCloud、腾讯云、七牛云、百度云加速这些能为我们提供免费服务的CDN服务商,它们让我们这些草根站长能见识的更多,拥有更多可能,谢谢。

官方微信
返回顶部