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


346

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

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

[{requestedResource:"Roman"}] 

これ400"blah"フィールドがまったく存在しない場所として扱う必要がありますか?

[{blah:"Roman"}]

34
多分402、彼らが本当に価値を送ることができることを望んでいるなら、彼らはRomanあなたにもっとあなたに支払う必要があるだけです:)
Jason Sperske

これを見た実際のシナリオ-PUT呼び出しを行ってデータを追加しました。同じリクエスト本文を使用してもう一度put呼び出しを行ったところ、前のリクエストがすでに処理されていることを伝える400が返されました。システムがそのデータを追加するのに時間がかかるのは通常のことです。
MasterJoe2 2017

回答:


361

400は、リクエストが不正な形式であることを意味します。言い換えると、クライアントからサーバーに送信されたデータストリームはルールに従っていませんでした。

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

そのロジックにより、あなたが提供した両方のシナリオは400のはずです。

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


3
「その論理により、あなたが提供したシナリオはどちらも400年代であるはずです」までは私も同感です。ここではJSONの内容は重要ではないと思います。あなたは、不正な形式私はあなたがJSON内のフィールドをスキップする場合は、送信データの形式でアドレスの問題は、たとえば、あなたが400を得るべきであると信じていたいと言うとき
Geethanga

2
restapitutorial.com/httpstatuscodes.htmlには、適切なREST応答コードのセットがあります。また、許可されていない406(Not Acceptable)または405メソッドなどの有効なリクエストをどのように処理するかによっても異なります。ただし、「不正な構文のためにサーバーがリクエストを理解できなかったため、400が適切です。クライアントは変更なしでリクエストを繰り返すべきではありません。」
Andrew Scott Evans

3
したがって、「構文が正しくないため、サーバーはリクエストを理解できませんでした」は、リクエスト(たとえば、HTTPヘッダーの1つが不正)か、リクエストによって運ばれるデータ(たとえば、JSON値がない)のいずれかです。 ?
MC皇帝

2
Vidyaは、「XMLはスキーマ検証に合格しない」と述べています。重要な点は、XMLパーサーは、整形式(つまり、構文的に健全)なドキュメントと有効(つまり、スキーマに応じて意味的に健全)なドキュメントを区別することです。400コードの説明は「不正な構文のため、サーバーはリクエストを理解できませんでした」です。つまり、検証エラーには使用しないでください。
マーティン・リー

@Vidyaはstackoverflow.com/questions/42851301/...あなたが私にしてください助けを知っていれば、私もこのエラーに似同じ問題に直面しています。このエラーを見てみましょう
モハンGopi

74

w3.orgから

10.4.1 400不正なリクエスト

不正な構文のため、サーバーはリクエストを理解できませんでした。クライアントは変更せずにリクエストを繰り返すべきではありません。


10
エラー400を返す正当性は、フィールドと値ではなく、リクエスト全体に基づいています。HTTP 400は良い方法だと思います
Jason Sperske 2013年

400応答を使用して、リクエスト内のURL、ヘッダー、ボディなど、ボディだけでなく何かが間違っている可能性があることをクライアントに通知することを意味しますか?
MasterJoe2 2017年

3
urlの場合、正しいコードは404です。ヘッダーの場合、これは大げさだと思います。403(禁止)は、ヘッダーがIDを拒否している場合の正しい方法のようですが、ヘッダーが出力形式を決定している場合はどうなりますか?400で正しいと思う唯一のパスについては、意味がなく、繰り返さないでくださいアクションが要求されている状況です。私は4年前にこの回答を書きました。最近では、エラーでも200が返されるべきだと感じています。そのエラーは、HTTP送信にのみ適用され、ペイロードには適用されません。
Jason Sperske、2017年

1
この回答はこれの多くをカバーしていますが、まだすべてのチャートを読んでいませんが、stackoverflow.com
a / 34324179/16959

@JasonSperskeロードバランサー、プロキシ、その他のミドルウェアは、ステータスコードを使用して、ルーティング、レポート、修復を支援します。幸い、 "422"のようなコードは明示的にペイロードに関するものであるため、ペイロードステータスコードの仕様にはある程度の余地があります。
Erik Aronesty

53

HTTP応答コードの選択は非常に簡単な作業であり、単純なルールで記述できます。しばしば忘れられる唯一のトリッキーな部分は、RFC 7231の段落6.5です。

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

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

  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"
}

21

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

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

一方、パラメーター値のエラーはセマンティクスのエラーです。これは、おそらく妥当性が検証されていないユーザー入力によるものです。これはHTTPエラーではありません(ただし、422である可能性があります)。処理パスは異なります。

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


4
+1、P HTTPでの略プロトコル及び応答はHTTPエラーである場合、それは低レベルの問題であるべきです。torazaburoによって記述されたアプローチを使用して、長年にわたってコードの複雑さの多くを回避しました。HTTPエラーで頻繁に爆破する代わりに、私たち全員が弾力性のあるコードを作成した場合、RESTランドの痛みは少なくなります。
Dem Pilafian 2016

25
200は、リクエストが処理されたことを意味するため、通常の成功ロジックをクライアントで実行する必要があります。ここには間違いなくエラーがあるため、応答に2xxまたは3xxコードを含めることはできません。5xxにすることもできません。これはサーバー側のエラーであり、クライアント側でエラーが発生するためです。したがって、これは4xxエラーである必要があります。しかし、応答本文のエラーの説明は正しいことであり、実際にはHTTP仕様で推奨されている方法です。
Alexey Guseynov 2016

ロガー、プロキシ、その他のツールには422がより良い
Erik Aronesty

16

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

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

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

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

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


3
いいえ、415は、エンティティは、例えば、間違ったタイプのものであると主張されたときのためにあるimage/gifの代わりtext/jsonContent-Type:ヘッダー。-おそらくこれは、マルチパートのコンポーネントに誤ったタイプが指定されている場合にも当てはまります。詳細については、422について説明しているtools.ietf.org/html/rfc4918を参照してください
Jasen

8

期待について考えます。

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


5

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

私はjavascript変数があると仮定し、

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

以下のようにformData、keyの値として変数を直接使用しないでください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); 
    }
});

とにかく、他の人が示したように、エラーはサーバーがリクエストの形式が正しくない構文を引き起こしたことを認識できなかったためです。実際にはインスタンスを発生させています。それが誰かに役立つことを願っています。


4

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

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

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


http 400エラーが発生しました。リクエストに特殊文字が含まれていることを確認しました。これを修正するために、コンテンツタイプにcharset = UTF-8を渡しました。
Kislay Kishore 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.