统计本站访问情况,发现一个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";
}
}
部署步骤
后台插件页上传启用即可。由于采用插件模式来处理这个问题,切换主题也会持续生效。
© 一梦风神 · 本文采用 CC BY-NC 4.0 协议共享
