サーバー上のファイル名に残る文字コードの落とし穴
古いウェブサイトを調べていると、ページ本文は表示できても、画像やリンク先のファイルだけが見つからないことがあります。文字が「???」に置き換わったり、ファイル名の一部が空白になったり、クリックすると404エラーが返ったりする現象です。こうした問題は、HTMLの記述ミスだけでなく、サーバー上に保存されたファイル名の文字コードと、ブラウザーが送信するURLの表現が一致していない場合にも発生します。
特に、フレームを使った古い日本語サイトでは、ページ本体、メニュー、画像、別ウィンドウの文書が複数のファイルに分かれていました。管理者が異なる環境でファイルを移動したり、サーバー会社を変更したりすると、ファイル名だけが別の文字コードとして解釈されることがあります。画面に表示されるサイト名や画像が壊れていても、背後にあるパス情報やリンク構造から原因を推測できる場合があります。
日本語のファイル名で問題になりやすいのは、UTF-8、Shift_JIS、EUC-JP、ISO-2022-JPなどの違いです。これらは同じ日本語を表現できても、バイト列は同じではありません。サーバーのファイルシステムに記録されたバイト列、ウェブサーバーが解釈するURL、ブラウザーが送信するパーセントエンコード後の文字列が少しでも異なると、見た目が似た名前でも別のファイルとして扱われます。
また、文字コードの問題は、単純な「文字化け」とは限りません。濁点や半濁点の結合方式、全角と半角、機種依存文字、予約文字の扱い、OSごとの大文字・小文字の規則も影響します。ファイル名を安全に保ち、古いサイトを移行するには、表示されている文字だけで判断せず、実際のバイト列とリクエストの内容を確認する必要があります。
文字コードの違いがファイル名を変える仕組み
コンピューターは、ファイル名を人間が見る「文字」として保存しているわけではありません。最終的には、一定の規則に従った数値の並び、つまりバイト列として記録します。UTF-8で保存した「資料」という名前と、Shift_JISで保存した同じ「資料」は、画面上では同じに見えても、内部のバイト列が異なります。作成時と参照時の規則が違えば、サーバーは目的のファイルを発見できません。
古い日本語サイトでは、HTMLがShift_JISで書かれている一方、サーバー上のファイル名はEUC-JPで作られているような混在も起こりました。HTMLのcharset指定はページ本文の解釈方法を示すものですが、必ずしもファイルシステム上の名前の保存形式まで統一するものではありません。そのため、ページの日本語が正常に見えても、画像の参照先や添付文書のリンクだけが失敗することがあります。
URLでは、非ASCII文字をそのまま送らず、UTF-8を基準にパーセントエンコードするのが一般的です。たとえば日本語のファイル名がURLに含まれると、ブラウザーは文字を%と16進数の組み合わせに変換します。しかし、古いサーバーや独自のCGIが別の文字コードを前提にしていると、その変換結果を正しく戻せません。URLのデコードを二重に行う実装や、逆に一度も行わない実装も、同じような不具合を引き起こします。
リンクに含まれるパラメーターやエンコードの変化を確認する際は、リンク解析の技術資料のような資料も参考になります。ファイル名そのものだけでなく、ブラウザーが送信したリクエスト行、リダイレクト先、サーバーログに残ったパスを順番に照合することが重要です。
古い日本語サイトで起きやすい表示の崩れ
フレーム構成のサイトでは、最初に読み込むフレーム定義ファイルが、複数の子ページを相対パスで指定します。親ページが正常に開いても、子フレームのファイル名に日本語や特殊記号が含まれていると、そこだけ読み込みに失敗することがあります。メニュー側の文字コードと本文側の文字コードが違う場合には、リンクをクリックした瞬間に別の名前へ変換されるため、原因の所在が分かりにくくなります。
画像の拡張子や大文字・小文字も見落としやすい点です。Windowsで作成したBanner.JPGが、Linuxサーバーではbanner.jpgと別物になることがあります。さらに、FTPソフトがファイル名をローカルの文字コードからサーバー側の想定へ変換する設定を持っていると、転送時に名前が変わることがあります。転送後に見た目の名前だけを確認しても、元の文字が正しく保存されたかは判断できません。
古いページには、URLに空白、丸括弧、番号記号、アンパサンドなどが含まれている場合もあります。これらはURL上で特別な意味を持つため、文字コードが正しくてもエスケープが不十分だと別のパスとして解釈されます。日本語の濁点が分離した文字として保存されている場合には、同じ表示に見える文字列をコピーしても一致しないことがあります。
このようなサイトを調べるときは、ブラウザーの開発者ツールで「Network」欄を確認し、実際に要求されたURL、ステータスコード、リダイレクトの有無を記録します。サーバー側ではアクセスログとエラーログを同じ時刻で照合します。404ならパスの不一致、400なら不正なURL形式、403ならアクセス権やサーバー規則が原因である可能性が高く、文字コードだけに決めつけない姿勢が必要です。
保存時と転送時に生じる変換
ファイル名の問題は、サーバーに置いた時点で発生するとは限りません。ローカルのファイル管理ソフト、圧縮ファイル、FTPクライアント、バックアップ媒体を経由するたびに、名前の解釈方法が変わる可能性があります。特に古い圧縮形式では、ファイル名の文字コードを明示する共通仕様が弱く、作成した環境と展開した環境が異なると日本語名が崩れます。
FTPには、転送するファイルの内容を変換するモードがあります。テキストモードでは改行コードが変わることがありますが、設定やソフトウェアによってはファイル名の扱いも影響を受けます。SFTPやHTTPSによる転送は通信の安全性を高めますが、ファイル名の文字コードが自動的に統一されるわけではありません。転送前後の一覧をUTF-8で保存し、ハッシュ値と併せて比較すると、名前と内容の変化を切り分けやすくなります。
Linux系の環境では、ファイル名をバイト列として扱える範囲が広く、表示用の端末が解釈できない名前でも保存されることがあります。一方、Windowsでは予約名、末尾の空白やピリオド、使用できない記号に制限があります。macOSではUnicodeの正規化に関する挙動が問題になることもあります。開発用パソコンでは開けるのに本番サーバーでは失敗する場合、OSの違いとファイルシステムの仕様を並べて確認します。
バックアップから復元するときも、元のアーカイブ内に記録されたファイル名を確認しなければなりません。復元ツールが自動的にUTF-8へ変換していれば、古いHTMLに書かれた参照先と名前がずれることがあります。反対に、元のShift_JISをそのまま復元した結果、現在のウェブサーバーがUTF-8として解釈してアクセス不能になることもあります。復元前に一覧を取り出し、変換方針を決めてから実行するのが安全です。
安全な命名と移行の進め方
新しく公開するファイルは、英字、数字、ハイフン、アンダースコアを中心に命名すると、文字コードに起因する問題を大幅に減らせます。たとえば「会社案内_最終版.html」の代わりにcompany-profile-v2.htmlのような名前を使い、画面に表示する日本語はHTML本文やページタイトルで表現します。日付や版数を名前に含める場合も、全角数字や記号を避け、規則を文書化しておくと担当者が変わっても混乱しません。
すでに日本語ファイル名が大量に存在する場合、いきなり名前を変更すると外部サイトや検索エンジンからのリンクが切れます。まず新しい英数字の名前へ複製し、旧URLから301リダイレクトを設定します。移行期間中はアクセスログを確認し、旧パスへの要求が残っていないかを調べます。画像、CSS、JavaScript、RSS、サイトマップ、配布資料内のリンクも対象に含めなければ、見えるページだけ直して終わることになります。
文字コードの変換は、エディターで開いて保存するだけで済ませず、変換前後の一覧を機械的に比較します。ファイル名の変換では、Unicode正規化、濁点の結合状態、全角記号、長すぎる名前、末尾の空白を検査します。変換できない文字を単純に削除すると同名ファイルが生まれる可能性があるため、衝突時の連番付与や置換規則をあらかじめ決めておきます。
移行作業には、検証用の別ホストを用意します。主要なブラウザーとスマートフォンから、トップページ、フレーム内の各リンク、画像、PDF、フォーム送信、古いブックマークを確認します。サーバーのOS、ウェブサーバー、プログラミング言語、データベースがそれぞれ異なる文字コード設定を持っていないかも調べます。問題が起きたURLは、見た目の文字列ではなく、リクエストのバイト列とレスポンスヘッダーを保存して再現できるようにします。
記録と検証で原因を特定する方法
調査の最初に、対象ページのHTML、HTTPヘッダー、リダイレクト履歴、サーバーのエラーログを保存します。古いサイトでは、後から管理画面や元データにアクセスできなくなることがあります。画面のスクリーンショットだけでは、文字化けした名前が元々何だったのか分からないため、HTMLソースとネットワーク記録を別々に保管します。
次に、参照元に書かれたパスとサーバー上の実ファイル一覧を比較します。比較するときは、文字列を同じ文字コードへ変換してから行い、単純な目視比較を避けます。シェルで一覧を取得する場合も、端末のロケール設定によって表示結果が変わるため、標準出力をファイルに保存し、バイト列を確認できるツールで調べます。ログに記録された%E3%...のような表記は、何回デコードされたものかを明確にします。
再現テストでは、問題のファイル名を一つに絞り、UTF-8のURL、旧来の日本語エンコードを想定したURL、手動でパーセントエンコードしたURLを順に要求します。どの形式で200が返り、どの形式で404になるかを比較すれば、変換の境界を推測できます。ただし、本番環境へ大量の試行を行うとアクセス制御に触れる場合があるため、管理者の許可を得て低頻度で実施します。
古いサイトの案内や関連情報を確認する場合は、運営情報を確認できるフォーラムのような関連ページも、表示の崩れだけで判断せず、リンク先の構造や取得日時と併せて扱います。サイトのタイトルや画像が欠落していても、それだけで特定のサービス内容を断定することはできません。確認できた事実、推測、未確認の情報を分けて記録することが、復旧作業と調査結果の信頼性を守ります。
文字コードの統一は、過去のファイルをすべて同じ形式へ変換することだけが目的ではありません。利用者が確実に目的のリソースへ到達でき、管理者が再現可能な方法で保守できる状態を作ることが目的です。英数字の命名、UTF-8を基本としたHTML、明示的なURLエンコード、リダイレクト管理、定期的なリンク検査を組み合わせれば、古い構成からの移行後も同じ問題を繰り返しにくくなります。
まず対象サーバーのファイル一覧とアクセスログを保存し、文字コード、Unicode正規化、URLエンコード、OS差異の四つを分けて確認してください。日本語の名前を変更する場合は、旧URLの対応表とリダイレクトを用意し、検証環境で画像や文書まで開けることを確かめてから本番へ反映します。記録を残しながら一つずつ照合することが、壊れたファイル名を安全に読み解き、長期的に安定したサーバー運用へつなげます。