広告が嫌いですか? 行く 広告なし 今日

実際にあなたを傷つけるHTTPステータスコード — 301と302、401と4-03、そして5xxの危険地帯

掲載日

辞書ではない。実際に生産環境で発生する問題を引き起こすHTTPステータスコードに関する焦点を当てたガイド。永遠にキャッシュされてしまう誤ったリダイレクト、401/403の混同による認証ロジックの漏洩、Retry-Afterが指定されていない429、および503と504の混同により、誤ったレイヤーをデバッグするような問題。

実際にあなたを傷つけるHTTPステータスコード — 301と302、401と403、そして5xxの危険地帯1

リダイレクトを送信しましたが、正しいタイプではありません。以前にそのリダイレクトにアクセスしたすべてのブラウザがそれを永続的にキャッシュしており、修正する唯一の方法はキャッシュの有効期限が切れるのを待つか、ユーザーにブラウザの履歴をクリアしてもらうことです。これは301です。

これはステータスコード辞書ではありません——そのような辞書はたくさんあります。テーブルを読んだ後でも間違ったコードを送信した場合に読むべきガイドです。実際にバグを引き起こすものを通じて、永続的なキャッシュが一時的なものに変わった、認証エラーが情報を漏らす、適切に処理されていないレート制限応答、および誤ったレイヤーを指すゲートウェイタイムアウトについて説明します。

301 と 302 と 307 と 308:リダイレクトマトリクス

誰もが少なくとも一度間違えること:あなたが 301 Moved Permanently をテスト中に使用しています。それはうまくいきます。あなたは進んでいきます。そして、もう一度構造を変更します。そして、その変更を前に訪れたユーザーの一部——つまり、2回目の変更前に訪れたユーザー——が、古い目的地に永遠に送られ、そのブラウザにキャッシュされています。

301 は永続的であり、積極的にキャッシュされます。 ブラウザは、あなたが Cache-Control ヘッダーを設定していない限り、キャッシュされたリダイレクトのTTLをほぼ無限に設定します。ユーザーのブラウザからキャッシュを削除するためのプログラム的な方法はありません。URL構造をまだ決定中であれば、302を使用してください。

メソッドの保持問題は別の問題です。ブラウザが301または302を追跡するとき、 可能 (実際にはほとんど常にそうします)、POSTをGETに下げる場合があります。これは元のHTTP/1.0仕様の違反ですが、ブラウザがそれほど昔からそれを標準として受け入れたため、RFC 7231はそれが標準的な行動であると認めています。POSTをリダイレクトする場合(たとえば、フォームの提出後)で、メソッドが保持されるべきであると期待するなら、307または308を使用する必要があります。

コード永続的?メソッドを保持?使用する場合
301はいいいえ(POST → GET)GETがリダイレクト後に問題ない永続的なURL移動
302いいえいいえ(POST → GET)一時的なリダイレクト、機能フラグ、A/Bテスト
307いいえはいメソッドを保持する必要がある一時的なリダイレクト
308はいはいメソッドを保持する必要がある永続的なリダイレクト

308のサポートは今、しっかりしています——Chrome、Firefox、Safari、Edgeすべてが正しく処理しています。ただし、一部の古いAPIクライアントやHTTPライブラリはまだ308を正しく処理していないため、マシン間のトラフィックをリダイレクトしていて、クライアントやそのHTTPライブラリを制御できない場合は、明示的にテストする必要があります。

401 と 403:認証と認可の違い

401は「あなたが自身を認証していない」と意味します。 仕様は、クライアントに認証方法を示す WWW-Authenticate ヘッダーを含む必要があります。無効なセッション、無効なトークン、またはトークンが期限切れの場合に正しいコードです。

403は「私はあなたが誰であることを知っていますが、答えはいいえです」と意味します。 ユーザーは認証されていますが、権限がありません。期限切れのトークンに対して403を返すのは間違い——それは401です。有効だが十分な権限を持たないリクエストに対して401を返すことも間違いであり、さらに、認証デバッグを混乱させます:あなたは欠落した認証を検索するようになりますが、実際の問題はロール割り当てです。

404を403に返すというセキュリティ上の主張は現実です。APIが を403で返すと、すべての攻撃者がそのエンドポイントが存在することを知り、それにはより高い権限が必要であると理解します。404を返すことで、リソースの存在についての情報が漏れません。これは判断の問題です:403は技術的に正しいし、デバッグがしやすいですが、存在の可視性が重要なセンシティブエンドポイントでは404が安全な選択です。 429:リート制限はRetry-Afterなしでは無意味です GET /admin/users429応答に

ヘッダーがない場合、ブラックボックスになります。クライアントはリート制限されたことを知っていますが、100msか24時間待つべきかわかりません。ほとんどのクライアント実装は即座にリトライ(リート制限を打ち抜く)または完全に諦めます。

は、待機時間(秒)またはHTTP日付(リトライする時刻)として取ります: Retry-After ヘッダーはどのRFCにも含まれていません——GitHubのAPIから生まれた従来の標準です。それらを

Retry-After と共に含めましょう。Limit/Remaining/Resetのトリオは、壁に到達する前にクライアントがどこにいるかを示し、壁に到達しただけを知っているよりも有用です。

HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1749254400

X-RateLimit-* 一つだけ強調すべき点があります: Retry-Afterは503応答にも有効であり、同じ意味を持ちます——「この秒数後に戻ってください」。サービスがメンテナンスモードで一時的に利用不可の場合、503応答とともに

を送信する必要があります。単に接続を切断するのではなく。 Retry-After 503 と 504:失敗はどこにあるか? Retry-After これらは似ていますが、まったく異なる失敗層を指しており、混同するとデバッグが間違った方向に行きます。

は、アクセスしたサーバーが現在処理できていないことを意味します——オーバーロード、メンテナンスモード、またはバックエンドの依存関係がダウンしています。サーバー自体が応答したため、単に仕事を受け入れないだけです。

504 ゲートウェイタイムアウト

503 Service Unavailable は、プロキシまたはゲートウェイ(ロードバランサ、nginx、APIゲートウェイ、CDN)が上流サーバーにアクセスし、タイムアウト前に応答を得られなかったことを意味します。アクセスしたサーバーは生きています。その背後にあるサービスは応答していません。

実際には:nginxに隠れている場合、アプリケーションサーバー(Node、Rails、Djangoなど)がクラッシュした場合、502 Bad Gatewayになります——nginxは応答を得ましたが、それはゴミでした。アプリケーションサーバーが完全に応答しなくなった場合、504になります。アプリケーション層から意図的にエラーを返した場合、503になります。この違いはトラブルシューティングにおいて重要です:504は上流サービス、タイムアウト設定、ネットワークを調べるべきです。503はアプリケーション自体を調べるべきです。 422 と 400:バリデーションエラーには独自のコードがあります

は、サーバーが解析できないリクエスト——不正なJSON、不正なクエリ文字列構文、必要なヘッダーの欠如——に対して使用されます。これは構造的な問題です。

は、サーバーが理解したが、データのバリデーションに失敗したリクエストに対して使用されます——開始日が終了日より後の日付範囲、無効なメールアドレスのフィールド、負の数量フィールド。リクエストは文法的に問題ありませんでした。意味論的に間違っていました。

400 Bad Request 多くのAPIは、これらを400にまとめて、バリデーション詳細をレスポンスボディに隠しています。これは機能しますが、クライアント側のエラーハンドリングを難しくします:クライアントはボディを解析して、パースエラーかバリデーションエラーかを判断しなければなりません。バリデーションエラーに対して422を使用することで、クライアントはステータスコードにキーを置くことができます。Railsは長年これを行っており、JSON:API仕様もバリデーションエラーに対して422を指定しています。

422 Unprocessable Entity 一つのニュアンス:422はWebDAV(RFC 4918)で定義されており、HTTP仕様の核心には含まれていません。実際にはこれは意味がありません——すべてのHTTPクライアントとサーバーがそれを処理しています——しかし、時々、厳密な人が400を使用すべきだと主張します。彼らは正確ではありません。しかし、422はより特定かつ広く理解されています。

204 と 200 で空ボディ:DELETEの場合の正しいもの

DELETEが成功した場合、正しい応答は

——200で空ボディ、または200で

204は「成功し、応答ボディが意図的に存在しない」という明確なシグナルです。200で空ボディは技術的に有効ですが、曖昧です——クライアントはボディが存在するべきだったが失われたのか、それとも意図的に存在しないのかを知りません。204はその曖昧性を除去します。 204 No Content PUTおよびPATCHで更新されたリソースを返さない場合にも同じ論理が適用されます。APIがPATCH後に更新されたオブジェクトを返す場合、200を使用します。返さない場合、204を使用します。200で空のボディを返すのは204がコスチュームを着ているだけです。 {"success": true}.

一つの注意点:

204はメッセージボディを含めないでください {} または null RFC 9110に従って。204を返した場合に誤ってボディを含めると(一部のフレームワークが許容する)、一部のHTTPクライアントは無事に処理し、他のクライアントは処理できません。レスポンスハンドラーでボディを削除するのではなく、意図で削除する必要があります。

迅速にデバッグ中にどのステータスコードを確認する必要がある場合、 IO Tools には HTTP ステータスコードリファレンスがあります が、範囲全体をカバーし、説明と各コードの使用タイミングについてのノートを提供しています。

すべてのこれらのパターンの背後にあるパターン

コード意味一般的な誤り修正
301永続的なリダイレクトテスト中に使用しているが、それが永遠にキャッシュされているリダイレクトが永続的であることを確認するまで302を使用してください
302一時リダイレクトPOSTがリダイレクト後にGETに下がるメソッドを保持する必要がある場合、307を使用してください
307一時的なリダイレクト(メソッド安全)302と混同しているPOST/PUT/PATCHを一時的にリダイレクトする場合に使用してください
308永続的なリダイレクト(メソッド安全)301に慣れていて、メソッドが重要である場合にスキップしているメソッドが重要である場合、301ではなく307を使用してください
400不正なリクエスト(パースエラー)バリデーションエラーにも使用しているバリデーションに失敗した場合、422を使用してください
401未認証ユーザーが権限を持っていない場合に返される(403が正しい)認証情報が欠落または期限切れの場合にのみ401を返してください
403Forbiddenセキュリティに敏感なエンドポイントでは404を返すエンドポイントの存在を隠すことが重要な場合、404を検討してください
422処理できないエンティティ400にまとめてあるパース可能なボディを持つバリデーション失敗に対して422を使用してください
429リート制限されたRetry-Afterヘッダーがない常にRetry-After + X-RateLimit-*ヘッダーを含めてください
503サービスが利用不可504と混同しているアクセスしたサーバーがリクエストを処理できない場合に使用してください
504ゲートウェイタイムアウト503と混同している上流サービス、ゲートウェイのタイムアウト設定、ネットワークを調べるべきです
204コンテンツなし200で空ボディを返している成功したDELETE/PUT/PATCHで応答ボディがない場合に204を使用してください

デバッグ中に迅速にステータスコードを確認する必要がある場合、 IO Tools には HTTP ステータスコードリファレンスがあります が、範囲全体をカバーし、説明と各コードの使用タイミングについてのノートを提供しています。

すべてのこれらのパターンの背後にあるパターン

これらの誤りの多くは同じ場所から来ています:ステータスコードを「4xxはクライアントエラー、5xxはサーバーエラー、終了」という緩いカテゴリとして扱っていること。ステータスコードはプロトコルの特定の意味を持つため、クライアント——ブラウザ、HTTPライブラリ、CDN、モニタリングツール——が実際にそれらにキーを置くのです。CDNは200と204を同じようにキャッシュしません。HTTPクライアントは400と503を同じロジックでリトライしません。ブラウザは302と301を同じTTLでキャッシュしません。

正しいコードを使用してください。オーバーヘッドはゼロです。何かが壊れたときにデバッグのメリットはそれほどではありません。

広告なしで楽しみたいですか? 今すぐ広告なしで

拡張機能をインストールする

お気に入りのブラウザにIOツールを追加して、すぐにアクセスし、検索を高速化します。

に追加 Chrome拡張機能 に追加 エッジ拡張 に追加 Firefox 拡張機能 に追加 Opera 拡張機能

スコアボードが到着しました!

スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!

ニュースコーナー 技術ハイライト付き

参加する

価値ある無料ツールの提供を継続するためにご協力ください

コーヒーを買って