【htaccess】URLの最後に「/」を付ける方法

URLの最後が拡張子がつかないパターン(ディレクトリやindex.htmlで省略時)のとき、「/」があっても無くてもページは表示されます。このときどちらかに統一しておきたいことがあるかと思います。

今回対応したいページがあったので、htaccessを使って「/」有りに統一する方法をメモしておきます。

htaccessでURLの最後に「/」を付ける方法

<IfModule mod_rewrite.c>
RewriteEngine on
#「/」補完
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.[^/\.]+$
RewriteRule .* %{REQUEST_URI}/ [R=301,L]
</IfModule>

↑こちらを「.htaccess」に追記すると、URLの最後に「/」を追加できます。
※編集する際はバックアップしてからお試しください

実装は以上で完了となります。
以下、簡単にですが、一通り説明を書いておきますので、興味のある方はご覧ください。
※ちなみにメインは4~6行目です

1行目と7行目(IfModule)

<IfModule mod_rewrite.c>
・・・
</IfModule>

モジュール(mod_rewrite.c)が使える場合に「・・・」の処理を行います。言い換えると、モジュールが使えない場合は、「・・・」の処理は何も行われないということです。

基本的に「mod_rewrite」を利用できる環境がほとんどですが、サーバによっては利用できない場合もあるかもしれません。

もし動作しない場合は、「htaccessの設定ミス」または「モジュール(mod_rewrite.c)が使えない」が考えられます。htaccessに問題がなさそうな場合は、レンタルサーバやサーバ管理者にご確認ください。

2行目(RewriteEngine on)

RewriteEngine on

「mod_rewrite」を有効にします。

3~5行目(RewriteCond)

#「/」補完
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.[^/\.]+$

3行目はコメントです。

4行目、5行目は、アクセスしたURLの最後がファイル名(company.htmlなど)以外で、かつ、「/」が付いていなければ、という処理になります。

各記号の説明をしますね。不要な方は6行目(RewriteRule)まで飛ばしてください。

RewriteCondとは?

RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.[^/\.]+$

RewriteCond」とは、半角スペース以降に条件(%{REQUEST_URI} !/$など)が書かれていて、その条件が満たされた場合に次の行の処理を行うという命令です。

今回の場合、5行目も「RewriteCond」になっています。こういった場合はAND条件になります。つまり、「4行目を満たす」かつ「5行目を満たす」ならば「6行目を処理する」となります。

OR条件にしたい場合

[OR]を「RewriteCond」の行の最後にスペースをあけて付ければOKです。

RewriteCond %{REQUEST_URI} !/$ [OR]
RewriteCond %{REQUEST_URI} !\.[^/\.]+$

%{REQUEST_URI}とは?

RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.[^/\.]+$

%{REQUEST_URI}とは「REQUEST_URI」という環境変数を使うための形です。「%{}」で囲むと環境変数の値を利用できます(環境変数は他にもいくつかあります)。

環境変数「REQUEST_URI」の値はURLのドメインを除いた部分です。このページの場合ですと、URLが「https://lucklog.info/htaccess-url-end-slash/」なので、「/htaccess-url-end-slash/」となります。

「¥」とは?(正規表現)

RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.[^/\.]+$

」はエスケープ文字です。「\.」は「.」という文字を指します。「.」のように文字以外の機能を持つ文字を文字として扱いときに「\.」のように文字の前にエスケープ文字を付けます

「!」とは?(正規表現)

RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.[^/\.]+$

「!」とは否定です。よって、「!/」は「/」ではない、「!\.」は「.」ではないという意味になります。

[^~]とは?(正規表現)

RewriteCond %{REQUEST_URI} !\.[^/\.]+$

[^~]とは「~」以外を意味します。「~」には2文字以上指定でき、「かつ」になります。
よって、[^/\.]「/」「.」以外となります。

「+」とは?(正規表現)

RewriteCond %{REQUEST_URI} !\.[^/\.]+$

+」は直前の文字を最低1文字以上必要という意味になります。よって、「[^/\.]+」の意味は「/」「.」以外の文字列が1文字以上です。
※(例)OK⇒「a」「test」など、NG⇒「/」「.」

「$」とは?(正規表現)

RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.[^/\.]+$

$」は直前の文字が行の末尾にある場合にマッチします。よって、「!/$」は末尾が「/」ではない、「[^/\.]+$」は「/」「.」以外の文字が1文字以上で終わる文字列となります。

6行目(RewriteRule)

RewriteRule .* %{REQUEST_URI}/ [R=301,L]

アクセスしてきたURLの末尾に「/」を付けたURLにリダイレクトします。

本ページであれば、「https://lucklog.info/htaccess-url-end-slash」でアクセスされた場合、「https://lucklog.info/htaccess-url-end-slash/」にリダイレクトされるということです。

以下各機能・記号の説明です。

RewriteRule
URL の書き換えを行います。1つ目のスペースの後の「条件パターン」に一致する URL を、2つ目のスペースの後の「置換文字列」で書き換えます。
「.」(正規表現)
任意の1文字
「*」(正規表現)
直前の文字が 0回以上 繰り返す
「.*」の場合、どんな文字列でもという意味
[R=301,L]
R=301は、リダイレクトを行います。ちなみに、URL変更を伝えるので、今までのページの評価は落ちません
Lは、ここで終了という意味です。

まとめ

ゴチャゴチャと書きましたが、アクセスされたURLの末尾に「/」が無いけど付けれる場合、「/」をつけてリダイレクトするよということです。

<IfModule mod_rewrite.c>
RewriteEngine on
#「/」補完
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.[^/\.]+$
RewriteRule .* %{REQUEST_URI}/ [R=301,L]
</IfModule>

↑こちらを「.htaccess」に追記すると、URLの最後に「/」を追加できますので、必要な方はコピペしてご利用くださいね。
※バックアップはお忘れなく

ちなみに、下記のようなページを作成したのですが、URL末尾に「/」を付けたかったので、今回の記事を書きました。

https://colorcode-to-rgb.luck-jp.com/ffff00/

以上、誰かのお役に立てれば幸いです。