400 BADリクエストHTTPエラーコードの意味?

2013年10月30日に質問されました。  ·  閲覧回数 1.1M回  ·  ソース

Phoenix picture
2013年10月30日

HTTPURLに投稿しているJSONリクエストがあります。

requestedResourceフィールドは存在するが、 "Roman"がこのフィールドの無効な値である場合、これを400として扱う必要がありますか?

[{requestedResource:"Roman"}] 

これは400として扱われるべきで、 "blah"フィールドはまったく存在しませんか?

[{blah:"Roman"}]

回答

Vidya picture
2013年10月30日
365

400は、リクエストの形式が正しくないことを意味します。 つまり、クライアントからサーバーに送信されたデータストリームがルールに準拠していませんでした。

JSONペイロードを持つRESTAPIの場合、400は通常、正しく言えば、サービスのAPI仕様に従ってJSONが何らかの方法で無効であることを示すために使用されます。

その論理により、提供した両方のシナリオは400秒になるはずです。

代わりに、これがJSONではなくXMLであると想像してください。 どちらの場合も、未定義の要素または不適切な要素値が原因で、XMLがスキーマ検証に合格することはありません。 それは悪い要求でしょう。 ここで同じ取引。

Jason Sperske picture
2013年10月30日
75

w3.orgから

10.4.1400不正なリクエスト

構文が正しくないため、サーバーは要求を理解できませんでした。 クライアントは、変更せずに要求を繰り返すべきではありません(SHOULDNOT)。

Alexey Guseynov picture
2016年09月23日
54

HTTP応答コードの選択は非常に簡単な作業であり、簡単なルールで説明できます。 忘れられがちな唯一のトリッキーな部分は、RFC7231の6.5項です。

HEAD要求に応答する場合を除いて、サーバーは、エラー状況の説明と、それが一時的または永続的な状態であるかどうかを含む表現を送信する必要があります。

ルールは次のとおりです。

  1. リクエストが成功した場合は、2xxコード(リダイレクトの場合は3xx)を返します。 サーバーで内部論理エラーが発生した場合は、5xxを返します。 クライアントリクエストに問題がある場合は、4xxコードを返します。
  2. 選択したカテゴリから利用可能な応答コードを確認します。 そのうちの1つがあなたの状況によく一致する名前を持っている場合、あなたはそれを使うことができます。 それ以外の場合は、x00コード(200、400、500)にフォールバックします。 疑わしい場合は、x00コードにフォールバックしてください。
  3. 応答本文にエラーの説明を返します。 4xxコードの場合、クライアント開発者が理由を理解してクライアントを修正するのに十分な情報が含まれている必要があります。 セキュリティ上の理由から5xxの場合、詳細を明らかにする必要はありません。
  4. クライアントがさまざまなエラーを区別し、それに応じてさまざまな反応を示す必要がある場合は、機械可読で拡張可能なエラー形式を定義し、APIのあらゆる場所で使用します。 最初からそれを作るのは良い習慣です。
  5. クライアント開発者が奇妙なことをして、人間が読める形式の説明として返す文字列を解析しようとする可能性があることに注意してください。 そして、文字列を変更することによって、そのようなひどく書かれたクライアントを壊します。 したがって、常に機械可読な説明を提供し、テキストで追加情報を報告しないようにしてください。

したがって、あなたの場合、「Roman」がユーザー入力から取得され、クライアントが特定の反応を示す必要がある場合、400エラーと次のようなものが返されます。

{
    "error_type" : "unsupported_resource",
    "error_description" : "\"Roman\" is not supported"
}

または、開発者が何か間違ったことをしない限り、そのような状況がクライアントの悪い論理エラーであり、予期されない場合は、より一般的なエラー:

{
    "error_type" : "malformed_json",
    "error_description" : "\"Roman\" is not supported for \"requestedResource\" field"
}
user663031 picture
2014年07月07日
23

どちらの場合も、「構文の不正」ではありません。 間違っているのはセマンティクスです。 したがって、IMHO 400は不適切です。 代わりに、 { "error": { "message": "Unknown request keyword" } }などの何らかのエラーオブジェクトとともに200を返すのが適切です。

クライアントの処理パスを検討してください。 構文エラー(無効なJSONなど)は、プログラムのロジックのエラー、つまり、ある種のバグであり、403と同様の方法でそれに応じて処理する必要があります。 言い換えれば、何か悪いことがうまくいかなかったのです。

一方、パラメータ値のエラーは、おそらく検証が不十分なユーザー入力が原因であるセマンティクスのエラーです。 これはHTTPエラーではありません(422の可能性があると思いますが)。 処理パスは異なります。

たとえば、jQueryでは、500などのアプリ固有のセマンティックエラーの両方を処理する単一のエラーハンドラーを作成する必要はありません。 他のフレームワーク、たとえばEmberも、400や500などのHTTPエラーを大きなファットエラーと同じように扱い、プログラマーが何が起こっているかを検出し、それが「実際の」エラーであるかどうかに応じて分岐する必要があります。

Cochise Ruhulessin picture
2016年09月23日
18

400ステータスコードを、リクエストの形式が正しくないことを示す以外の目的で使用することは、まったく間違っています。

リクエストペイロードにapplication/jsonとして解析できなかったバイトシーケンスが含まれている場合(サーバーがそのデータ形式を予期している場合)、適切なステータスコードは415です。

リクエストのエンティティが、リクエストされたメソッドのリクエストされたリソースでサポートされていない形式であるため、サーバーはリクエストの処理を拒否しています。

要求ペイロードが構文的には正しいが意味的には正しくない場合は、非標準の422応答コード、または標準の403ステータスコードを使用できます。

サーバーは要求を理解しましたが、それを実行することを拒否しています。 承認は役に立ちません。リクエストは繰り返されるべきではありません。

film42 picture
2013年10月30日
9

期待について考えてください。

クライアントアプリとして、サーバー側で問題が発生したかどうかを知る必要があります。 blahが欠落している場合、またはrequestedResource値が正しくない場合にサーバーがエラーをスローする必要がある場合は、400エラーが適切です。

Ankur Bhutani picture
2017年02月20日
6

最初にURLが間違っている可能性があることを確認し、正しい場合は送信しているリクエスト本文を確認します。考えられる原因は、送信しているリクエストに正しい構文がないことです。

詳細については、リクエスト文字列に特殊文字がないか確認してください。 (特殊文字)が使用されている場合、これがこのエラーの根本的な原因です。

リクエストをコピーして、すべてのタグデータを分析してみてください。

Eugene picture
2019年02月21日
6

補足として、私と同じ問題が発生する可能性がある人のために、フォームデータをサーバーに投稿するために$.ajaxを使用していますが、最初は400エラーも発生しました。

私がjavascript変数を持っていると仮定します。

var formData = {
    "name":"Gearon",
    "hobby":"Be different"
    }; 

以下のように、変数formDataをキーdataの値として直接使用しないでください。

$.ajax({
    type: "post",
    dataType: "json",
    url: "http://localhost/user/add",
    contentType: "application/json",
    data: formData,
    success: function(data, textStatus){
        alert("Data: " + data + "\nStatus: " + status); 
    }
});

代わりに、JSON.stringifyを使用して、以下のようにformDataをカプセル化します。

$.ajax({
    type: "post",
    dataType: "json",
    url: "http://localhost/user/add",
    contentType: "application/json",
    data: JSON.stringify(formData),
    success: function(data, textStatus){
        alert("Data: " + data + "\nStatus: " + status); 
    }
});

とにかく、他の人が示しているように、エラーはサーバーがリクエストの原因となる構文の形式を認識できなかったためです。実際にはインスタンスを作成しているだけです。 それが誰かに役立つことを願っています。