htaccessで404へリダイレクトする方法?

直リンクで画像やPDFファイルをしていた時、掲載期間が終了したものを削除した場合、何も設定していない場合、サーバエラー(500)が出てくる。500だと見た人がびっくりしちゃうから、404エラーページを作って安心(?)させようねって魂胆。

燐華

結構特殊ケースだと思う。公式LINEのカードタイプリストとかで使えるかもね

ErrorDocument命令

サーバの内部リダイレクトを使って404ページに移動させる。
ただしループに検知しにくい性質があるため、00エラー(Internal Server Error)になる可能性がある。

# 404エラー時に 404.html を表示
ErrorDocument 404 /test/404.html

無限ループを強制回避 RewriteEngine

ファイルがあれば表示、なければ404.htmlを表示という条件分岐をはっきりと記述する。
途中で処理を終了させる命令([L])を挟むため、ループを物理的に回避できる。

RewriteEngine On

# 1. もしリクエストされたファイルが実在するなら、そのまま表示して終了
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

# 2. 404.html 自体へのアクセスも、ループさせずに終了
RewriteRule ^404\.html$ - [L]

# 3. それ以外の「存在しないファイル」へのアクセスは 404.html を表示
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ 404.html [L]
  • [L]フラグ: 「Last」の略。この条件に合致したら、これ以降の行は読み飛ばして終了するという意味。これが無限ループを防ぐ鍵。
  • !-f: 「ファイルが存在しない場合」という否定の条件。

RewriteEngine On

「今から書き換えを始める」という宣言。

RewriteEngine On

1つ目のルール:実在するなら何もしない

  • RewriteCond(条件):リクエストされたファイル名が、サーバ上に実在する【-f】ならば
  • RewriteRule(実行):何もせずにそのまま表示する(-)
    • [L](終了):これ以降のルールは無視して終了

404.html自体や、まだ削除していないチラシ画像は、ループに巻き込まれずに正しく表示される。

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

2つ目のルール:end.htmlへのループを防ぐ

もしアクセス先が404.htmlそのものだったら、そこで処理を完全にストップ[L]。無限ループを物理的に断ち切るストッパーです。

※\. のようにバックスラッシュ(または円記号)がついているのは、正規表現で「ただの点」として扱うためのエスケープ処理です。

RewriteRule ^404\.html$ - [L]

3つ目のルール:存在しないなら飛ばす

  • RewriteCond:リクエストされたファイルが存在しない(!-f)であれば
  • RewriteRule:すべて(^.*$)を404.htmlとして表示する

ここでファイルがないときの処理が動く。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ 404.html [L]

  • X