定義と結論
404と500はサーバーが返すHTTPステータス、CORSとMixed Contentは主にブラウザが適用するセキュリティ制約です。 どれも画面では「読み込めない」と見えますが、失敗した層が違います。
| 表示 | 意味 | 最初に見る場所 |
|---|---|---|
| 404 | 対象URLのリソースを見つけられない | NetworkのURLと応答 |
| 500 | サーバー内部で予期しない失敗 | Networkとサーバーログ |
| CORS | 別オリジン応答をJavaScriptへ公開できない | Console、Headers、preflight |
| Mixed Content | HTTPS文書から安全でないHTTP資源を要求 | ConsoleとRequest URL |
エラー名を検索して設定を変える前に、「誰が止めたか」「HTTPリクエストは送られたか」「応答は返ったか」を確認します。
なぜ区別が必要か
原因の層を誤ると、効果のない修正や危険な回避策につながります。404にCORSヘッダーを追加してもファイルは現れません。500をフロント側で握りつぶしてもサーバー障害は残ります。CORSを避けるためブラウザの保護を無効化するのは、利用者の環境で成立する修正ではありません。
同じリクエストで複数の問題が重なることもあります。 APIが404を返していてもCORSヘッダーがなければ、JavaScriptからは詳細を読めず、ConsoleにはCORSエラーが目立つ場合があります。一つ直した後に次のエラーが見えるのは珍しくありません。
登場人物と「オリジン」
通信には、ページを表示するブラウザ、JavaScript、Webサーバー、API、リバースプロキシ/CDNなどが関わります。サーバーログへ到達していなければ、ブラウザ、DNS、TLS、プロキシまでの層を疑います。
オリジンは原則としてscheme、host、portの組み合わせです。
https://app.example.com:443
https://app.example.comとhttps://api.example.comはhostが違うため別オリジンです。パスが違うだけなら同一オリジンです。CORSは別オリジンの読み取りを安全に許可する仕組みであり、同一生成元ポリシーを無効にする機能ではありません。
リクエストから表示までの流れ

- ページやJavaScriptがURLを組み立てる
- HTTPSページならブラウザがMixed Contentに当たらないか評価する
- 別オリジンの特定リクエストではOPTIONSのpreflightを送る
- DNS、接続、TLSの後、対象サーバーへHTTPリクエストが届く
- ルーターが対象を探し、処理結果として404、500、2xxなどを返す
- 別オリジンならブラウザがCORS応答ヘッダーを確認する
- 条件を満たす場合だけJavaScriptが応答を読める
この順序を知ると、Networkにリクエストがない、OPTIONSだけ失敗、GETは500だが本文を読めない、といった違いを説明できます。
404 Not Found
404は、サーバーが要求を受けたものの、対象を見つけられなかったことを示します。
GET /images/logo.png → 404 Not Found
原因にはURLの誤字、大文字小文字、ベースパス、デプロイ漏れ、動的ルートの値、プロキシの転送先があります。APIでは「エンドポイントがない」と「指定IDのデータがない」の両方で404を使う設計があります。Response本文とAPI仕様を確認します。
SPAでは、ブラウザから/courses/1を直接開くとホスティング側がファイルを探して404にする場合があります。この場合はアプリ内ルーターではなく、サーバーのfallback/rewrite設定が論点です。
500 Internal Server Error
500は、サーバーが要求の処理中に予期しない状態へ陥ったことを表す一般的なステータスです。例外、DB接続、環境変数、外部API、テンプレート処理など原因は多岐にわたります。
ブラウザから分かるのは、どの入力でいつ失敗したかまでです。スタックトレースや秘密情報を利用者へ返さず、サーバーログでリクエストIDと時刻を照合します。入力不備を何でも500にせず、仕様に応じて400系を返すと、利用者側の修正可能性が伝わります。
CORS
CORSはCross-Origin Resource Sharingの略です。別オリジンからのfetchなどに対し、API側がAccess-Control-Allow-Origin等で読み取りを許可します。許可がなければ、通信そのものが行われてもブラウザはJavaScriptへ応答を渡しません。
単純ではないメソッドやヘッダーでは、ブラウザが先にOPTIONSを送って許可メソッド・ヘッダーを確認します。これがpreflightです。OPTIONSが404、認証リダイレクト、500になると本来のPOSTは送られません。
Cookieなど資格情報を含める場合は、クライアントの設定とサーバーのAccess-Control-Allow-Credentialsが必要で、許可オリジンに*は使えません。許可対象は必要なオリジンに絞ります。
CORSは認証・認可の代わりではありません。 CORSを通らないクライアントもサーバーへ直接要求できます。APIはトークン、セッション、権限を独立して検証します。
Mixed Content
HTTPSページからHTTPの画像、script、fetchなどを読み込むと、安全なページへ盗聴・改ざん可能な経路が混ざります。ブラウザは種類に応じて自動アップグレードまたはブロックします。
https://example.com
└─ http://api.example.com/data
原因は本番に残ったhttp://localhost、古いCMSデータ、外部埋め込み、プロキシ後のURL生成などです。URLをHTTPSへ変えるだけでなく、相手が有効なHTTPSを提供しているか確認します。CORSヘッダーを追加してもMixed Contentの解決にはなりません。
主要パターンの比較
| 観察 | 有力な原因 | 担当になりやすい場所 |
|---|---|---|
| GETが404 | パス・ルート・デプロイ | フロント設定、サーバールート |
| GETが500 | アプリ内部の例外 | API、DB、外部連携 |
| OPTIONSが失敗 | preflight未対応 | API、プロキシ、認証middleware |
| 2xxだがJSで読めない | CORS応答ヘッダー | API/CORS設定 |
| HTTPS画面からHTTP URL | Mixed Content | URL設定、配信元 |
| Networkに記録がない | JS未実行、URL生成前の例外等 | フロントコード |
具体例:本番の問い合わせAPI
本番ページhttps://www.example.com/contactがhttp://api.example.com/messagesへPOSTすると、まずMixed Contentで止まる可能性があります。API URLをHTTPSへ直すと、今度はOPTIONSが404になるかもしれません。APIのルーターやプロキシでOPTIONSへ正しく応答し、許可オリジンをhttps://www.example.comにすると本POSTが届きます。
その後POSTが500なら、CORSではなくサーバー処理の問題です。サーバーログで入力検証、DB、メール送信を調べます。このように、表示された順に層を一つずつ直し、毎回Networkを取り直します。
よくある誤解
CORSはサーバー間通信でも同じように止める
CORSを強制する主体は主にブラウザです。サーバーからAPIへの通信は同一生成元ポリシーの対象ではありません。ただしAPIの認証は必要です。
mode: "no-cors"で解決できる
通常、応答がopaqueになりJavaScriptからstatusや本文を読めません。API連携の解決策ではなく、サーバー側の許可を正しく設定します。
404ならサーバーは落ちている
404応答を返せているため、少なくとも応答したHTTPサーバーは存在します。目的のアプリへ届いたかはHeadersや応答本文で確認します。
500は必ずコードのバグである
コード以外にも設定不足、容量、接続先障害があります。ログと監視情報から事実を確認します。
HTTPSページなら中の通信も自動でHTTPSになる
コードやデータに絶対HTTP URLがあれば混在します。環境ごとのAPI URLを確認します。
注意点とベストプラクティス
- CORSで
*を安易に使わず、必要なorigin、method、headerだけ許可する - Originを文字列の部分一致で判定せず、正規化した許可リストと厳密に比較する
- 500応答にスタックトレース、SQL、環境変数を含めない
- 404と500にリクエストIDを付け、利用者向け文言と内部ログを分ける
- HTTPSを本番全体で使い、API・画像・フォント・埋め込みも点検する
- ブラウザ拡張や保護無効化を正式な修正にしない
- curlで成功しただけでブラウザのCORSも成功すると判断しない
デバッグと確認方法
DevToolsのConsoleとNetworkを開き、Preserve logを有効にして再現します。NetworkでInitiator、Request URL、Method、Statusを確認し、OPTIONSがあれば本リクエストと分けて見ます。Request HeadersのOrigin、Response HeadersのAccess-Control-Allow-Origin、許可method/headerを比較します。
404では最終URL、base path、大小文字、デプロイ成果物、rewriteを確認します。500では時刻、リクエストID、入力条件をサーバーログと照合します。Mixed ContentではConsoleに示されたHTTP URLをコード、環境変数、CMSデータから探します。
ブラウザとサーバーで観測を分けることも重要です。サーバーログにないなら到達前、ログにあり応答もあるのにJSから読めないならCORSが有力です。エラー文より先に、URL、method、status、headers、到達ログを一枚の時系列に並べると切り分けが速くなります。
まとめ
404は対象なし、500はサーバー内部失敗、CORSは別オリジン応答の公開条件、Mixed ContentはHTTPSページへの安全でない通信の混在です。HTTP応答なのかブラウザ制約なのかを分け、Network、Console、サーバーログを同じリクエストで照合します。保護機能を無効にするのではなく、原因の層で設定・URL・処理を直すことが正しい解決です。