web-dev-qa-db-ja.com

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

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

これはrequestedResourceフィールドが存在するが400がこのフィールドには無効な値である"Roman"として扱うべきですか?

[{requestedResource:"Roman"}] 

これは400フィールドがまったく存在しない"blah"として扱うべきですか?

[{blah:"Roman"}]
318
Phoenix

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

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

その論理によって、あなたが提供したシナリオは両方とも400のはずです。

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

339
Vidya

w3.org から

10.4.1 400不正なリクエスト

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

67
Jason Sperske

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"
}
48
Alexey Guseynov

どちらの場合も「構文の形式が正しくありません」。それは間違っている意味論です。したがって、私見400は不適切です。代わりに、{ "error": { "message": "Unknown request keyword" } }などの何らかのエラーオブジェクトとともに200を返すことが適切です。

クライアント処理パスを検討してください。構文の誤り(例えば無効なJSON)はプログラムの論理の誤り、言い換えればある種のバグであり、それに応じて403と同じように扱われるべきです。言い換えれば、悪いことが間違っています。

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

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

20
user663031

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

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

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

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

サーバーは要求を理解しましたが、それを満たすことを拒否しています。承認は助けにならないでしょうし、要求は繰り返されるべきではありません。

12

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

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

7
film42

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

詳しく述べるには、リクエスト文字列の中の特殊文字を調べてください。それが(特殊文字)使用されている場合、これがこのエラーの根本的な原因です。

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

3
Ankur Bhutani

補足として、私と同じ問題に遭遇するかもしれない人のために、私は$.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); 
                }
            });

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

1
Gearon