存在しないURLが200を返す静的サイトで、リンク切れを見逃さない
今回やったこと
HTTP 200は、要求したページが正しく存在することを必ずしも意味しない。静的サイトの配信構成によっては、見つからないパスにトップページを返し、ステータスだけは200にすることがある。公開後チェックがステータスコードだけを見ていると、存在しない画像や内部リンクを正常と誤判定する。この挙動を検出し、欠落を見分ける二段構成を導入した記録である。
対象は、静的サイトをCDN経由で配信し、公開後にリンクや画像を自動確認している開発者だ。サイト構成の設定に加え、監視側でも応答内容を検査する方法を扱う。
200だけではページの存在を確かめられない
従来の単純な確認は、URLを取得してステータスが200なら正常とする。しかし、配信側のfallbackが存在しないURLをトップページへ書き換える場合、欠落した画像への要求にもHTMLのトップページが返りうる。検査は成功と判断する一方、読者のブラウザでは画像が表示されない。
このサイト群で起きた事例では、画像や内部リンクが欠落した記事が、ステータスコードだけのチェックを通過して公開されていた。別のサイトでも同じ配信条件が残っていたため、個別のページを直すだけでなく、同種の静的サイト全体を対象に確認方法を揃える必要があった。
| 検査方法 | 見つけられるもの | 弱点 |
|---|---|---|
| HTTPステータスのみ | 明示的な404など | fallbackが200を返すと欠落を見逃す |
| 応答本文の指紋 | トップページを返すcatch-all | 本文が変化すると一致判定が難しい |
| Content-Typeの確認 | 画像URLにHTMLが返る状態 | 期待する形式の定義が必要 |
| 配信側の404ページ | 不在を正しい状態コードで返す | 設定変更でページが消える可能性がある |
一つの検査にすべてを任せない。配信設定で正しい404を返し、監視側でも実体の応答を見て、設定がずれたときに検知できるようにする。
配信側と検査側の二段構成
根本側では各サイトに404ページを用意し、存在しないURLに適切な不在応答を返す。これにより、ブラウザや通常の検査ツールが期待するHTTPの意味に近づける。ただし404ページがビルド対象から外れたり、配信ルールが変わったりすれば、設定がいつの間にか効かなくなる可能性がある。
そこで保険として、検査側は「存在しないことが確実なパス」を一度取得し、その応答をcatch-allの基準として記録する。検査対象のURLが200を返した場合でも、本文のハッシュやページタイトルが基準と一致すれば、実体ではなく代替ページが返ったと判定できる。画像の場合はContent-Typeも確認し、画像を期待するパスにHTMLが返っていないかを見る。
実装では、本文全体の指紋とページタイトルの両方を使う。本文全体の完全一致だけでは、時刻表示などでページがわずかに変わったときに見逃すためだ。画像は通常のページ本文とは異なるので、画像形式のContent-Typeを独立して確認する。HEADリクエストを受け付けない配信先では、必要に応じてGETへ切り替えられる設計にする。
運用での確認ポイント
公開後検査を作るときは、正しいURLだけでなく、確実に存在しないURLを使った対照も用意する。存在しないパスが404になること、仮に200になっても本文やContent-Typeで欠落と判定できることを確かめる。実在するページを誤って欠落扱いしないテストも必要だ。
また、サイトの404ページを追加しただけで完了にしない。ビルドや配信設定の変更後に同じゲートが動くようにし、監視側の検査も継続する。根本対処と検知のどちらか一方に依存すると、将来の設定ずれが静かな成功として残る。
この方法は、HTTP 200のすべてを疑うものではない。応答コード、本文の特徴、コンテンツ種別を組み合わせて、要求したリソースに対する応答かを確かめる。小さな追加チェックで、公開済みページの見かけ上の成功と実際の欠落を区別できる。
更新履歴
- 2026-10-05: 初稿を作成。