存在しないURLが200を返す静的サイトで、リンク切れを見逃さない

  • #Astro
  • #Cloudflare Pages
  • #監視
存在しない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: 初稿を作成。