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失效

发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注