IT実践

WordPressリダイレクトプラグインで日本語を扱えるように修正

  • このエントリーをはてなブックマークに追加
  • LINEで送る

WordPressに301リダイレクトを設定するSimple 301 Redirectsというプラグインを導入しました。

PukiWikiで運用していた旧コンテンツをWordPressに引き継いだ後に、Google Search Consoleのクロールエラー対策&SEO対策です。

PukiWikiからのデータ移行については下記の記事をご覧ください。

PukiWikiをWordPressに移行する方法に困って半手動で実施

WordPress用プラグイン Simple 301 Redirects

必須WordPress用プラグイン Simple 301 Redirects
Download WordPress公式サイト

Simple 301 Redirectsというプラグインですが、phpファイル1つだけで構成されていて、管理画面もURLを設定するだけという名前の通り非常にシンプルです。
Google Search Consoleでクロールエラーが出ているURLをコピーしてRequest欄に貼り付け、リダイレクト先のURLをDestination欄に貼り付けて「変更を保存」ボタンをクリック。

しかし挙動を確認するまでもなく、Request欄に貼り付けたはずのURLが一部消えてしまいます。
どうやらURLエンコードされている部分が消失してしまっているようです。

ソースコードを追いかけてみると、保存する前にWordPressの関数sanitize_text_fieldが呼ばれていました。
WordPress関数リファレンスを見ると、

オクテット(’%‘ に続く 2 桁の 16 進数)を除去します。

と明記されています。

これは日本語を含むURLの場合は致命的で、それ以外にも「/」を「%2F」にエンコードするような仕様でも困ったことになります。

プラグイン「Simple 301 Redirects」のカスタマイズ

セキュリティ的なリスクを承知の上で、wp-simple-301-redirects.phpの188行目と189行目にあるsanitize_text_field関数を削除しました。

wp-simple-301-redirects.php

変更前

for($i = 0; $i < sizeof($data['request']); ++$i) {
 $request = trim( sanitize_text_field( $data['request'][$i] ) );
 $destination = trim( sanitize_text_field( $data['destination'][$i] ) );

 if ($request == '' && $destination == '') { continue; }
 else { $redirects[$request] = $destination; }
}

変更後

for($i = 0; $i < sizeof($data['request']); ++$i) {
 $request = trim( $data['request'][$i] );
 $destination = trim( $data['destination'][$i] );

 if ($request == '' && $destination == '') { continue; }
 else { $redirects[$request] = $destination; }
}

管理画面にはそもそも私以外は入らないのと、登録するURLに怪しいコマンドが入っていないかを確認するというのが前提です。

これで無事に保存できるようになりました。
念のためデータベースのwp_optionsテーブルを確認してみましたが、正常に書き込まれています。

もう一つ問題が浮上。

「301リダイレクト」登録したのに「404 not found」が返ってくる

まあ一筋縄ではいかないとは思っていました。

wp-simple-301-redirects.php

変更前

}
elseif(urldecode($userrequest) == rtrim($storedrequest,'/')) {
 // simple comparison redirect
 $do_redirect = $destination;
}

変更後

}
elseif(urldecode($userrequest) == urldecode(rtrim($storedrequest,'/'))) {
 // simple comparison redirect
 $do_redirect = $destination;
}

242行目で「リクエストされたURL」と「保存されているURL」を比較していますので、ここに細工しました。

URLエンコードしたURLを登録した場合、比較する時にはURLデコードしなければ一致しませんね。

これで良しと思ってしばらく運用していたのですが、上記設定ではGoogle Search Console対策しか考えておらず、「https://example.com/日本語/?q=日本語」といったURLエンコードされていない日本語の入ったURLを考慮していませんでした。
ブラウザから送られてくる文字コードはUTF-8でエンコードされるのが主流になりつつありますが、登録するURLが別の文字コードでエンコードされていたり(PukiWikiは通常EUC-JPを吐き出します)、このSimple 301 Redirectsというプラグインは最近では珍しくEUCで書かれています。

先ほどと同じく242行目を修正します。

wp-simple-301-redirects.php

変更前

}
elseif(urldecode($userrequest) == rtrim($storedrequest,'/')) {
 // simple comparison redirect
 $do_redirect = $destination;
}

変更後

}
elseif(mb_convert_encoding(urldecode($userrequest), "UTF-8","auto") == mb_convert_encoding(urldecode(rtrim($storedrequest,'/')), "UTF-8","auto")) {
 // simple comparison redirect
 $do_redirect = $destination;
}

比較対象の文字コードを揃えます。
EUC-JPで揃えても良いのですが、昔perl時代にEUCだと一部の文字が正常に表示されなかった記憶があるのでUTF-8にしました。

これで以下の全てに対応できます。

  • 未エンコード
    /日本語/?q=日本語
  • EUC-JPでエンコード
    %2f%c6%fc%cb%dc%b8%ec%2f%3fq%3d%c6%fc%cb%dc%b8%ec
  • UTF-8でエンコード
    %2f%e6%97%a5%e6%9c%ac%e8%aa%9e%2f%3fq%3d%e6%97%a5%e6%9c%ac%e8%aa%9e

 

 

どうかこの記事へリンクを張ってください。

当コンテンツは、必要な情報がすぐに見つかるように広告をなるべく載せない方針でやっております。

僅かな広告でサイトを運営していくために、少しでも多くのアクセス数を必要としています。
当サイトの記事がもしお役に立ちましたら、記事の紹介やリンクをぜひお願いします。

※特にアフィリエイト広告は提灯記事になってしまいがちで、情報としての信憑性を欠くために掲載しません。

Webサイトをご紹介ください

コメントを残す

*