WordPress 4.4.2版本在设置固定链接后出现分类翻页异常(404)

为了配合WP Super Cache,必须对页面进行固定链接的设置,最初的设置是固定设置成/p=%post_id%的样子,如下图:
WordpressPermalinkSettingWrong

刚刚开始没发现异常,最近才发现,当一个分类的分页数量大于3页的时候,会出现打不开的情况。

当点击Android分类的时候,会发现文章分了11页,当点击第二页的时候,发现,链接地址中的"/"被替换成了"%2F",导致网页打不开,直接返回404,如下图的情况:

ReplaceBy%2F

搜索半天,用Ubuntu12.04下WordPress安装WP Super Cache后链接包含”%2F”导致分类链接返回404的方法总算是解决,本以为没问题了,结果当点击完成第二页,继续点击第三页的时候,继续出现无法访问,观察链接后,发现错的更离谱了。如下图:

ClickTheThirdPage

直接提示"该页无法显示"

URLInCorrect

仔细观察链接会发现,链接地址莫名的被增加了一段%2Fpage%2F2,明显是第二页的地址残留,于是手工去掉这个多余的信息,发现是可以正常访问的。

RemovedIncorrectUrl

这就比较扯淡了,说明是页面生成的时候发生了异常。应该是不能正确的处理链接地址中携带%2F这种转义字符的情况。

网上搜索很长世间,也没有任何的有用信息,结果重新修改了一下固定链接,修改成/%year%/%post_id%,结果一切正常了,由此可见,WordPress应该是只测试了一部分情况,只能处理固定格式的固定链接,随便修改会导致内部代码混乱。WordpressPermalinkSettingCorrect

如此修改后,链接地址中也不会出现"/"被替换成"%2F"的情况了。

Ubuntu12.04下WordPress安装WP Super Cache后链接包含”%2F”导致分类链接返回404

WordPress安装WP Super Cache后需要开启"固定链接",但是开启之后,发现在点击分类链接的时候,一旦出现多页,点击分页的时候返回404错误。
开始认为是重写规则设置得不对, 后来才发现, 是"%2F"导致Apache直接返回404错误.

比如浏览查看某个标签下的文章列表的链接为

http://www.mobibrw.com/p=/android/page/2

被重写后的URL变为:

http://www.mobibrw.com/p=%2Fandroid/page/2

这样"/"被替换为"%2F",当这个请求到达Apache的时候,被Apache直接返回404错误。
Apache有一个配置项"AllowEncodedSlashes", 默认是"Off", 也就是不允许请求路径(上例是 %2Fandroid/page/2)中包含编码后的斜杠'/'(在某些平台是反斜杠'\'). 这个选项的的相应代码在mod_rewrite模块被执行之前:

// request.c
AP_DECLARE(int) ap_process_request_internal(request_rec *r){
	if (d->allow_encoded_slashes) {
		access_status = ap_unescape_url_keep2f(r->parsed_uri.path);
	} else {
		access_status = ap_unescape_url(r->parsed_uri.path);
	}
}

// util.c
AP_DECLARE(int) ap_unescape_url(char *url){
	if (IS_SLASH(*x) || *x == '\0')
		badpath = 1;
	...
	else if (badpath)
		return HTTP_NOT_FOUND;
}

默认不允许包含"%2F". 如果请求路径中包含了, 那么ap_unescape_url()函数认为是无效的路径, 直接返回HTTP_NOT_FOUND, 最终浏览器得到的是"404 - Not Found"出错页面.

Apache的配置文件中增加AllowEncodedSlashes On即可.如下:

$sudo vim /etc/apache2/sites-enabled/000-default
ServerName www.mobibrw.com

<VirtualHost *:80>
        ServerName www.mobibrw.com
        ServerAlias www.mobibrw.com
        DocumentRoot /var/www/wordpress
        #当URL中存在%2F转义后的字符‘/’的时候,会直接返回404,因此需要设置此项
        AllowEncodedSlashes On
        <Directory />
                Options FollowSymLinks
                AllowOverride All
        </Directory>
        <Directory /var/www/wordpress>
                #Options Indexes FollowSymLinks MultiViews
                Options FollowSymLinks MultiViews
                AllowOverride All
                FCGIWrapper /usr/bin/php5-cgi .php
                Options ExecCGI SymLinksIfOwnerMatch
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

</VirtualHost>

参考链接


链接包含"%2F"导致mod_rewrite失效

大批WordPress网站被渗透 ,成为DDOS攻击源

1456369411312.jpg!small

近日,Sucuri的安全研究人员发现,数万WordPress站点被利用于实施第7层DDos攻击。共有两万六千个不同的WordPress站点持续向同一个网站以每秒一万到一万一千次的频率发送HTTPS请求,最多时能达到两万次每秒。更严重是,如果Pingback功能默认开启,全球任何一个WordPress站点都可能被利用,成为DDos攻击网络的一个源头。

HTTP Flood是针对Web服务在第七层协议发起的大规模流量攻击,不仅可以直接导致被攻击的Web前端响应缓慢,还间接攻击到后端的Java等业务层逻辑以及更后端的数据库服务,增大它们的压力,甚至对日志存储服务器都带来影响。

建议所有基于Wordpress的网站尽快禁用Pingback。虽然无法保证网站免于遭受攻击,但会终止黑客利用您的网站来攻击其它目标。

最好的做法是,如果你确定不用pingbacks,就和xmlrpc一并关闭。如果需要使用,可以简单修改.htaccess文件,只允许白名单中的IP来存取文件。流行插件Jetpack也可用于流量监控。

14562244766558.png!small

WordPress的pingback服务可被DDoS攻击利用,这个漏洞早有披露,但至今仍有大量网站存在此问题,原因在于网站所有者很少刻意防止网站被僵尸网络捕获。而由于这种DDoS攻击中流量来自数千个不同IP,基于网络的防火墙也无法识别和拦截,只能限制每个IP地址的访问频率。

1456224508906.png!small

研究人员还发现,大多数实施攻击的源网站托管在知名VPS/云服务提供商:亚马逊的AWS、Digital Ocean、谷歌云、微软的Azure、HETZNER、OVH和Linode。

原文地址:Thousands of WordPress websites used as a platform to launch DDOS

li 的点超出div

在Wordpress写文章的时候,发现列表项的数字总是在DIV标签的外面,如下所示

  1. 用户界面
  2. 视图导航
  3. 视图设置

HTML的源代码如下:

<div style="background-color: #f9f9f9; border: 1px">
<ol style="padding-bottom: 2px; margin-bottom: 2px; padding-top: 2px;">
	<li>用户界面</li>
	<li>视图导航</li>
	<li>视图设置</li>
</ol>
</div>

这种情况是非常不美观的,尤其是当DIV设置了背景色的时候。

网上查询了一下,发现list-style-position:inside是用来调整这种情况的。

语法:
list-style-position : outside |inside
取值:
outside :默认值。列表项目标记放置在文本以外,且环绕文本不根据标记对齐
inside :列表项目标记放置在文本以内,且环绕文本根据标记对齐
说明:
设置或检索作为对象的列表项标记如何根据文本排列。
假如一个列表项目的左外补丁(margin-left)被设置为 0 ,则列表项目标记不会被显示。左外补丁(margin-left)最小可以被设置为 30。
仅作用于具有display属性值等于list-item的对象。如li对象。
注意: ol对象和ul对象的type属性为其后的所有列表项目(如 li对象)指明列表属性。
此属性对于currentStyle对象而言是只读的。对于其他对象而言是可读写的。
对应的脚本特性为listStylePosition

 

因此修改上面的代码如下:

<div style="background-color: #f9f9f9; border: 1px ;font-size: small">
<ol style="padding-bottom: 2px; margin-bottom: 2px; padding-top: 2px;list-style-position:inside">
	<li>用户界面</li>
	<li>视图导航</li>
	<li>视图设置</li>
</ol>
</div>

修改后的效果如下:

  1. 用户界面
  2. 视图导航
  3. 视图设置

解决WordPress标题中数字英文字符串不能自动换行的问题

在发表文章的时候,如果标题中有长串的数字和英文字符,例如文件的路径、注册表路径、下载地址等,通常不能自动换行,从而造成溢出的部分要么延伸到侧边栏中,要么被隐藏,这都是不正常的。如下图所示:
TitleTooLong

解决这个问题的方法就是要在CSS样式表中加入换行控制代码。

操作方法如下:

1.用FireFox中的Firebug查看页面中标题的源代码
EntryTitleSrc
可以看到,Title部分的标题的源代码对应的是entry-title,字体大小为h2

2.修改对应主题的样式表(style.css),以Twenty Fifteen为例,在外观->编辑->style.css,源代码中搜索entry-title可以发现比较多,如下两处:

.entry-title,
.widecolumn h2 {
	font-size: 35px;
	font-size: 3.5rem;
	line-height: 1.2;
	margin-bottom: 1.2em;
}
.entry-title {
    font-size: 26px;
    font-size: 2.6rem;
    line-height: 1.1538;
    margin-bottom: 0.9231em;
}

我们增加word-wrap:break-word;word-break:break-all;告诉浏览器标题超长之后,主动换行,修改后的结果如下所示:

.entry-title,
.widecolumn h2 {
	font-size: 35px;
	font-size: 3.5rem;
	line-height: 1.2;
	margin-bottom: 1.2em;
	word-wrap:break-word;
	word-break:break-all;
}
.entry-title {
    font-size: 26px;
    font-size: 2.6rem;
    line-height: 1.1538;
    margin-bottom: 0.9231em;
    word-wrap:break-word;
    word-break:break-all;
}

如此修改之后,如果使用了WP Super Cache,则需要刷新缓存,如果没有使用WP Super Cache则直接刷新页面就可以了。

修改后的页面如下所示:

word_wrap_break_word

注意,只设置word-wrap:break-word;就可以满足需求,建议同时设置word-break:break-all;,效果会更好一些。

对于手机端来说,标题是h1大小的。使用Chrome查看手机端的网页的源代码是view-source:www.mobibrw.com就可以看到手机网页的源代码了。

解决开启 WP Super Cache 缓存时 WP-Postviews 1.71 不计数的问题

WP Super Cache的缓存插件可以有效地对动态网页进行缓存,降低主机资源的使用率,使得网站更加稳定。但是,这个插件也会导致别的插件工作不正常,比如这个统计访问次数的WP PostViews插件。

说下 WP Super Cache 的原理吧,是把所有的页面转化成静态html,然后再通过30X定向,绕后php直接访问静态html来加速,在有新评论和新文章时会更新缓存,而 WP-Postviews 原理是每次访问给meta加1,启用cache后不调用php文件了,所以自然不会计数。于是插件的作者通过ajax来增加计数。

我们以WP PostViews 1.7.1为例。

在PostViews的设置页面中点击允许使用Ajax进行计数统计,如下图:

PostViewsOptions

然后重新生成下缓存,就OK了。

这时候每次点击的时候后台会更新显示数,但是前台不会更新,下面我们来解决这个问题。

可以通过AJAX和DOM操作来解决。把下面的代码添加到wp-postviews.php文件尾部

function show_postview(){
	$views_options = get_option('views_options');
	$ID = $_POST["bigfa_view"];
	$custom_fields = get_post_custom($ID);
	$my_custom_field = $custom_fields['views'];
	foreach ( $my_custom_field as $key => $value ) {
		echo str_replace('%VIEW_COUNT%', number_format_i18n($value), $views_options['template']);
	}
	die;
}
add_action('wp_ajax_nopriv_show_postview', 'show_postview');
add_action('wp_ajax_show_postview', 'show_postview');

这段添加到postviews-cache.js文件尾部

jQuery(document).ready(function() {
	var ajax_data = {
		action: "show_postview",
		bigfa_view: viewsCacheL10n.post_id
	};
	 
	jQuery.post(viewsCacheL10n.admin_ajax_url, ajax_data,function(data) {
															jQuery('.show-view').html(data);
														});
	return false;
});

默认的调用方法是:

<?php 
	/*View Counter for  wp-postviews*/
	if(function_exists('the_views')) { the_views(); } 
?>

现在替换为

<span class="show-view">
	<?php 
		/*View Counter for  wp-postviews*/
		if(function_exists('the_views')) { the_views(); } 
	?>
</span>

或者

<span class="show-view">loading..</span>

这时候我们发现,文章页是正常计数的而且实时刷新,但是首页还是不行啊,这个没办法了,不过可以通过设置WP Super Cache,不缓存首页,这样就完美解决问题了。

参考链接:


解决开启 WP Super Cache 缓存时 WP-Postviews 不计数的问题

Wodpress主题底部显示当前网站备案号

后台备案号的设置是从 WP 3.7 开始的,查看网站根目录的 wp-config.php 文件,一般会看到 define('WP_ZH_CN_ICP_NUM', true); 这个定义,这个就是用来添加后台备案号设置的。如果你的 WP 版本在 3.7 以上,而且 wp-config.php 含有define('WP_ZH_CN_ICP_NUM', true);  就可以在后台 设置 - 常规 中看到配置选项。

icp

这个“ICP备案号”仅对WordPress自带主题有效。

如果使用的是第三方WordPress主题,因此不能享受到 WordPress 这个新添加的小功能实在是让人窝火。不过好在你只需要在自己所用的主题的footer.php中添加一行代码,即可让在WordPress 后台添加的ICP备案号显示出来了。

<a href="http://www.beian.miit.gov.cn/" rel="external nofollow" target="_blank">
<?php echo get_option( 'zh_cn_l10n_icp_num' );?>
</a>

如果你不希望链接到工信部网站,只添加下面的代码即可。

<?php echo get_option( 'zh_cn_l10n_icp_num' );?>

注意,由于工信部网站地址发生变动,导致上述操作之后,默认主题无法正常跳转到正确的工信部备案网站地址,需要对跳转地址进行修改具体修改方式请参考 解决WordPress 5.2.3后台ICP备案链接不能跳转到工信部网站(www.miitbeian.gov.cn)的问题

解决WordPress开启HTTPS后图片不能正常加载的问题

Apache2开启了Https支持,但是在Https打开网页的时候,发现,图片都不能正常的显示出来,看了一下源代码,发现是网页中的图片链接都被写成了HTTP的,导致浏览器出于安全的原因,不再加载图片,导致效果很差,因此需要WordPress同时支持HTTP,HTTPS。

找到当前主题下的 function.php 文件,编辑之,在里边代码的末尾追加如下代码:

/* 替换图片链接为 https */
function https_image_replacer($content){
	if( is_ssl() ){
		/*已经验证使用 $_SERVER['SERVER_NAME']也可以获取到数据,但是貌似$_SERVER['HTTP_HOST']更好一点*/
		$host_name = $_SERVER['HTTP_HOST'];
		$http_host_name='http://'.$host_name.'/wp-content/uploads';
		$https_host_name='https://'.$host_name.'/wp-content/uploads';
		$content = str_replace($http_host_name, $https_host_name, $content);
	}
	return $content;
}
add_filter('the_content', 'https_image_replacer');

参考链接:WordPress 开启全站 HTTPS

Ubuntu 12.04启用WordPress缓存插件WP Super Cache

WP Super Cache的基本介绍


WPSuperCache

WP Super Cache 是 WordPress 官方开发人员 Donncha 开发,是当前最高效也是最灵活的 WordPress 静态缓存插件。它把整个网页直接生成 HTML 文件,这样 Apache 就不用解析 PHP 脚本,通过使用这个插件,能使得你的 WordPress 博客将显著的提速。

WP Super Cache的缓存机制


WP Super Cache 缓存机制有三种,mod_rewrite 缓存模式 , PHP 缓存模式,传统缓存模式。

WP Cache 缓存时,会在你的“wordpress 安装文件夹/wp-content/cache/”文件夹下生成一系列wp-cache-xxxxxx.html格式的文件;Super Cache 缓存时,则在你的“wordpress 安装文件夹/wp-content/cache/supercache/”文件夹下生成对应每一篇文章或者标签等的目录。名称为xxx.html,取决于你的文章ID是怎么设置。目录下面就是静态的 index.html 文件。

当你一个访问者来的你的站点,他没有登入或者也没有留言,这样他得到是一个在 WordPress cache 文件夹下的 supercache 子文件夹下的纯静态文件,其实你都可以自己到上面的 supercache 目录下去查看同样的永久链接的 HTML 文件的备份。

判断一个页面是否已经被缓存了,查看该页面的源代码,如果访问者已经登陆或者留了言,就会返回 WP Cache 函数生成的页面,并且最后一行会有“Cached page generated by WP-Super-Cache+缓存时间”这行字,就像下面这行代码一样:

<!-- Cached page generated by WP-Super-Cache on 2016-01-17 17:47:16 -->

而 Super Cache 缓存会多一行如下代码:

<!-- super cache -->

因为 Super Cache 是真正静态的,对搜索引擎和博客的速度非常有好处,而且有效的减轻了 php 和 Mysql 的查询压力。这点对于大型博客来说优势很明显,一般的较小的博客感觉就不怎么明显。

WP-Super-Cache的使用设置


1.在插件页面中查找"WP Super Cache",然后安装即可。

2.在"设置"->"固定链接"中增加固定链接设置,建议如下设置:PermalinksSetting

注意:不要设置成"?/p=%post_id%",这样设置之后会导致无法在首页中打开分类目录,导致所有的分类都被重定向到了首页。

3.在插件页面中启用"WP Super Cache"。

4.页面中原有的链接,如果原来没有设置过"固定链接"的话,类似如下"http://www.mobibrw.com/?p=2969"的样子(比如站内的相互引用链接),不需要进行任何修改,只是这样访问不会缓存而已。

5.开启Apache2的mod_rewrite模块

$ sudo a2enmod rewrite

重启Apache2

$ sudo service apache2 restart

修改Apache2配置文件:

$ sudo vim /etc/apache2/sites-available/default

修改其中的:
AllowOverride NoneAllowOverride All

参考下面的修改:

DocumentRoot /var/www/wordpress
<Directory />
		Options FollowSymLinks
		AllowOverride All
</Directory>
<Directory /var/www/wordpress>
		#Options Indexes FollowSymLinks MultiViews
		Options FollowSymLinks MultiViews
		AllowOverride All
		FCGIWrapper /usr/bin/php5-cgi .php
		Options ExecCGI SymLinksIfOwnerMatch
		Order allow,deny
		allow from all
</Directory>

如果同时启用了Apache2的Https功能,则需要同时修改相同目录下面的default-ssl文件。

参考链接


WordPress缓存插件:WP Super Cache