.htaccessを使ったURLの正規化まとめ(wordpress対応)

この記事は最終更新から3年以上が経過しています。情報が古くなっている可能性があります。

こんにちは、しばです。
突然ですが、.htaccess ファイルって怖いですよね。なんとなく触ると急に画面が真っ白になって動揺させてくるファイルという認識です。

今回SSL化のリダイレクト設定ついでにURLの正規化を行う機会があったんですが、よそ様で紹介されている記述をコピったところリダイレクトループの罠にどハマり…(´Д`;)

いつも必要になる度に調べていたことでもあったので、この機会に調べてみました!

URLの正規化とは

正規化とは、検索エンジンが微妙なURLの違いによって評価を分散してしまうのを避けるための施策です。
例えば、「/index.php」と「/」など。
同じコンテンツを表示しているのに、URLが異なるため評価が分散されてしまい、本来より検索結果の順位が下がってしまいます。それを避けるために正規化を行います。

正規化を行うには、

  1. <link rel=”canonical”> タグを使用して検索エンジンが拾うURLを統一する
  2. .htaccess ファイルに正規化用のリダイレクトをいれることで、外部からの被リンク等を統一する

この2つの対応が必要になります。

canonical設定はGoogleなどの大手検索エンジンがサポートするURLを正規化するためのタグなので、検索エンジン対策としてはこちらがメイン、.htaccess ファイルでフォローするというイメージかなと思います。

(正直canonical設定はAMP専用の何かだと思ってた(^ω^;))

canonical設定はシンプルなので置いておき、.htaccess ファイルについて見ていきます。
まず前提として、今回動作確認した環境はロリポップのレンタルサーバになります。
レンタルサーバによってはこの書き方じゃうまく動かないこともあるようなので注意が必要です。

今回は以下の正規化を調べました。

  • HTTPからHTTPSへのリダイレクト
    例:「http://www.●●●.com/」→「https://www.●●●.com/」
  • 「●●●/index.●●●(拡張子)」から「●●●/」へのリダイレクト
    例:「https://www.●●●.com/index.php」→「https://www.●●●.com/」
  • 末尾に「/」(スラッシュ)が付いていないファイル以外のURLの場合、末尾「/」有りへのリダイレクト(トレイリングスラッシュとも言うようです)
    例:「https://www.●●●.com/aboutus」→「https://www.●●●.com/aboutus/
  • www無しから www有りへのリダイレクト
    例:「https://●●●.com/」→「https://www.●●●.com/」
  • パラメータ有りからパラメータ無しへのリダイレクト(WordPressだと出番はないかも知れませんが、パーマリンク構造によっては使ってもいいかも…)
    例:「https://www.●●●.com/test.php?p=123」→「https://www.●●●.com/test.php」

.htaccessの中身サンプル

.htaccessは上の記述から順に処理が行われるため、記述順が重要になります。
基本的には存在しないファイルへの対応(例:ファイルが存在しない場合特定のページへリダイレクトする)を上に書き、存在するファイルの対応(正規化等)は下に書くと良いとのこと。
正規化のみであれば順番はあまり気にしなくて良さそうです。

正規化は恒久的転送でいい場合が多い(ほとんど?)ので、301リダイレクトにします。

<Files ~ "^\.(htaccess|htpasswd)$">
	deny from all
</Files>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

### HTTPからHTTPSへ
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

### 「●●●/index.●●●(拡張子)」から「●●●/」へ
RewriteCond %{THE_REQUEST} ^.*/index.[A-Za-z]+ [NC]
RewriteRule ^(.*)index.[A-Za-z]+ https://example.com/$1 [R=301,L]

### 末尾に「/」(スラッシュ)が付いていないファイル以外のURLの場合、末尾「/」有りへ
# RewriteCond %{REQUEST_URI} !/$
# RewriteCond %{REQUEST_URI} !\.[^/\.]+$
# RewriteRule ^(.*)$ $1/ [R=301,L]

### www無しからwww有りへ
RewriteCond %{HTTP_HOST} ^example\.com
RewriteRule ^(.*) https://www.example.com/$1 [R=301,L]

### パラメータ有りからパラメータ無しへ
RewriteCond %{QUERY_STRING} !=""
RewriteCond %{REQUEST_URI} !(^/wp-admin/)
RewriteRule ^(.*)$ /$1? [R=301,L]
</IfModule>
order deny,allow


# BEGIN WordPress
<IfModule mod_rewrite.c>
   ### ~ 省略 ~
</IfModule>

# END WordPress

2019/1追記)末尾スラッシュはWordPressの場合htaccessで設定しない方が良さそうなのでコメントアウトしました。
詳細はこちら→「WordPressサイトのURLを正規化したらリダイレクトループが発生した

ちなみに、今回ひっかかったしよく記事でも見かけることなんですが、WordPressの場合は最初から以下のコードが書かれています。

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

正規化等自分で追記する場合は、このコードの上に書きましょう。このコードの中や下に書いても動かないので注意です。

ちなみに…

上のコードには入れてませんが、存在しないファイル・ディレクトリの場合に特定のURLへリダイレクトさせる場合はこのように書くようです。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

でもWordPressだとテーマの404.phpが優先されたりリダイレクトループから抜けられなくなったり、なぜかうまく動きませんでした。
サーバ環境か、.htaccess とWordPressの干渉とかかな…(・д・`m)

その場合は404.phpにリダイレクト設定をいれれば動いたので、動かなかったらそちらが安心かも知れません。


まとめたことで自分でちょっと安心しました(笑)
この記事で私と同じように.htaccessの恐怖が和らぐ方がいたら幸いです。

以上、「.htaccessを使ったURLの正規化まとめ」でした!