URLを静的化したら、404ページが表示されなくなった!
ほんとに?と思いますが、近場でもよく聞くトラブルの一つです。「URLを正規化したら404が表示されなくなった」と言われる場合もありますが、正規化にあたって動的URLを静的化したことが発端であることが多いのではと思います。
もちろん、きちんと設計・設定・処理をすれば「静的化によって404ページが表示されなくなる」なんてことは起こらないわけですが、いくつかの条件が重なると実際に起こってしまいます。サイトを公開した後に気が付いてもなかなか火消しが大変なので、そうなる前に。ほんの一例に過ぎませんが、実際にあった話を例に原因と対処方法を解説したいと思います。
とあるECサイトでの例
次のような仕様のECサイトにおいて、URLを静的化したことにより思わぬトラブルが起こりました。
ECサイトの標準仕様
1つの商品カテゴリを示すデータに次のような項目がありました。
カテゴリID | 2(自動採番) |
カテゴリ名 | グランフェアズ |
そのカテゴリページのURLは次のようになっていました。https://sampleshop.com/products/list.php?category_id=2
URLを静的化するためにカスタマイズ
「URLでどのカテゴリなのかを伝えたい」「分かりやすくしたい」という要件が出たため、新たに「カテゴリコード」データを追加。
カテゴリコード | granfairs |
「カテゴリID」ではなく「カテゴリコード」を使って次のようなURLになるようカスタマイズしました。
https://sampleshop.com/products/granfairs.html
実装・公開後に起こったこと
お客さまを含めプロジェクトメンバー皆大満足!でもその裏で…
次のような症状が起こっていました。
- 廃番になったカテゴリページにアクセスしてもエラーが出ない
- 旧URLでアクセスしても404ページが表示されない
どちらの場合も、エラー表示や404ページではなく、URLはアクセスしたまま(存在しないURL)で「カテゴリが選択されていないカテゴリページ」が表示されるようになっていたのです。
何が起こったのでしょう
廃番になったカテゴリページにアクセスしてもエラーが出ない
例えばアパレルメーカーは、モデルチェンジによって商品カテゴリ自体が廃番になったり、取扱をやめて使用しなくなるカテゴリが発生します。そのような「存在しないカテゴリページ」にアクセスがあった場合は、「ご指定の商品カテゴリは存在しません」といったエラーページが表示されるのが一般的です。
URLを静的化する前はエラーが出ていたのに、静的化したらエラーが出なくなりました。これは、静的化前は「カテゴリID」の有効/無効をチェックする機能が標準で実装されていたのに対し、静的化後の「カテゴリコード」については有効/無効をチェックする機能がないからです。
標準では、カテゴリページの表示に使用する条件は「カテゴリID」のみです。ページの表示条件を「カテゴリコード」にカスタマイズした時点でチェック機能がなくなるので、「カテゴリコードの有効/無効をチェックする機能」を追加しないといけなかった、わけです。
順序立てて説明すると「当然でしょう」と思うのですが、構築のタイミングでは「有効なカテゴリコード」を使って「静的化できているか」を中心に確認するため、コードを触った人以外は気づくことが難しい部類の穴だとも思います。ただ、このチェックがない=「あらゆる文字列をPHPに渡すことができる」ことになり兼ねないので、注意したいところです。
こちらは結構ツボる穴
旧URLでアクセスしても404ページが表示されない
例えばリニューアルする前に静的なURLとして/products/myfavorite.html
というページがあったとして、それがリニューアルにおいて不要になり、リダイレクトに値する新しいURLもないので、検索エンジンとユーザにページがなくなったことを伝えるため、404ページを表示させたいとします。
通常であれば何もしなくても無効なURLとしてステータス404が返ってきますが、上述の仕様の場合は「カテゴリコード=myfavorite
」として/products/list.php
にパラメータとして渡され、エラー処理がある場合はエラーページが、無い場合は「カテゴリが選択されていないカテゴリページ」が表示されてしまいます。URLはリクエストした/products/myfavorite.html
のまま、ステータスコードは200となり、404ページが表示されることはありません。
この旧URL/products/***.html
が多数、既にインデックス済みだった場合はどうでしょう?URLは消えず、404も出ず、コンテンツは重複してしまいます。
この状態で旧URLによるネガティブな影響を軽減するためには、旧URLに対し.htaccess
で強制的にステータスコード404を返すといった設定がまた必要になってきます。数が多いと一気にライフがゼロになります。。
こういったリスクを軽減するために出来ることは、静的化後のURL設計を事前にきちんとすることです。
静的化後のURL設計が大事
確かに/products/list.php?category_id=2
というURLが/products/granfairs.html
になると分かりやすくて素敵です。ただしこの設計には、次の2つの問題点があります。
- URLをリライトする条件が甘く、あらゆる文字列をPHPに渡す可能性がある
- 旧URLと同じURLパターンを採用したため、旧URLに対する404表示が難しくなった
例に上げたリライトの場合、.htaccess
の設定は次のようなものになります。(一部抜粋)
RewriteRule ^products/([0-9A-Za-z]+).html?$ products/list.php?category_code=$1 [L,QSA]
「カテゴリコード」に使用できる文字列に制約を設けていない場合、半角英数字・大文字小文字・文字数問わず全てを許容しlist.php
に渡すという処理になります。
システム側で、上述した「カテゴリコードの有効/無効をチェックする機能」を付けることでリスクを避けることができますが、チェック機能がない場合はかなり乱暴な対応になってしまいます。例え実害が発生しないとしても、避けたい設定です。
ではどうするか。静的化するURLに規則性を持たせ、制限を設けます。
例えば、/products/granfairs.html
とせず/products/cat-granfairs.html
のように接頭辞を付け、数字や大文字は許容しない、文字数にも制限を設ける、などです。
# 接頭辞あり, アルファベット小文字のみ, 10文字以下の条件を追加した場合の例
RewriteRule ^products/cat-([a-z]{1,10}+).html?$ products/list.php?category_code=$1 [L,QSA]
またこの作業を行うことで、多くの場合旧URLとのパターン重複も避けられることになり、404ページの表示に悩まされる心配もなくなります。
まとめ
静的化は、表示上簡単に実装できてしまう面があるので気軽にトライしてしまいがちですが、サーバの事、システムやパッケージの事、それに「何のためにやるのか」を分かっていないとうまく対応できないので、慎重に取り組むべき課題だと思います。実施の際は、事前調査と設計にある程度時間がかかることも分かってほしい!ですね。
URLの重複、正規化、静的化、404関係のトラブルは本当に原因がケースバイケースなので、今回の例が当てはまらないことが多いとは思いますが、原因究明のヒントになるとうれしいです。