WordPress URL编码大小写统一:解决%E与%e重复收录问题

统计本站访问情况,发现一个SEO问题:同一个页面,%E4%B8%AD%e4%b8%ad两个URL都能正常访问,而且都返回200状态码。搜索引擎会把这些URL当作不同的页面,导致权重分散、重复内容。下面这套解决方案直接可用。

为什么会出现这个问题

URL中的百分号编码(如%E4)在RFC规范里是不区分大小写的,但搜索引擎把URL路径当字符串处理。外部链接有人用大写、有人用小写,WordPress默认不做任何处理,就出现了同一个页面多个URL的情况。

解决方案:强制转小写 + Canonical同步

我的做法是把所有URL路径中的大写编码强制301跳转到小写版本,同时让canonical标签保持完全一致。

注意:我只处理URL的路径部分,?后面的参数完全不动,UTM跟踪码不会受影响。

直接上代码

新建一个独立插件文件,放在/wp-content/plugins/force-lowercase-url/force-lowercase-url.php

<?php
/**
 * Plugin Name: Force Lowercase URL Encoding
 * Description: 强制将URL路径中的大写百分号编码转为小写,并同步Canonical标签
 * Version: 1.0
 */

if ( ! defined( 'ABSPATH' ) ) exit;

// 301重定向:只处理路径,不碰参数
add_action( 'init', 'force_lowercase_encoding_redirect', 0 );
function force_lowercase_encoding_redirect() {
    $path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
    if ( empty( $path ) ) return;

    if ( preg_match( '/%[A-F]{2}/', $path ) ) {
        $norm = preg_replace_callback( '/%[A-F]{2}/', 
            fn( $m ) => strtolower( $m[0] ), 
            $path 
        );
        
        if ( $norm !== $path ) {
            $query = $_SERVER['QUERY_STRING'] ?? '';
            $target = home_url( $norm . ( $query ? '?' . $query : '' ) );
            wp_redirect( $target, 301 );
            exit;
        }
    }
}

// Canonical同步:适配主流SEO插件
add_filter( 'wpseo_canonical', 'force_lowercase_canonical' );
add_filter( 'rank_math/frontend/canonical', 'force_lowercase_canonical' );
add_filter( 'aioseo_canonical_url', 'force_lowercase_canonical' );

function force_lowercase_canonical( $url ) {
    if ( empty( $url ) ) return $url;
    $parsed = parse_url( $url );
    if ( isset( $parsed['path'] ) ) {
        $path = preg_replace_callback( '/%[A-F]{2}/', 
            fn( $m ) => strtolower( $m[0] ), 
            $parsed['path'] 
        );
        $scheme = isset( $parsed['scheme'] ) ? $parsed['scheme'] . '://' : '';
        $host = $parsed['host'] ?? '';
        $query = isset( $parsed['query'] ) ? '?' . $parsed['query'] : '';
        $fragment = isset( $parsed['fragment'] ) ? '#' . $parsed['fragment'] : '';
        return $scheme . $host . $path . $query . $fragment;
    }
    return $url;
}

// 无SEO插件时输出默认canonical
remove_action( 'wp_head', 'rel_canonical' );
add_action( 'wp_head', 'force_lowercase_default_canonical', 10 );
function force_lowercase_default_canonical() {
    if ( has_filter( 'wp_head', 'wpseo_canonical' ) || 
         has_filter( 'wp_head', 'rank_math/frontend/canonical' ) || 
         has_filter( 'wp_head', 'aioseo_canonical_url' ) ) {
        return;
    }
    $canonical = force_lowercase_canonical( home_url( add_query_arg( null, null ) ) );
    if ( $canonical ) {
        echo '<link rel="canonical" href="' . esc_url( $canonical ) . '" />' . "\n";
    }
}

部署步骤

后台插件页上传启用即可。由于采用插件模式来处理这个问题,切换主题也会持续生效。

发表评论

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

字数:0

字数:0