64

HTTP / 1.1仕様(RFC 2616)には、ステータスコード400、Bad Request(§10.4.1)の意味について次のように書かれています。

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

最近のいくつかのHTTPベースのAPIには、リクエストの構文エラーではなく論理エラーを意味するために400を使用する一般的な慣習があるようです。私の推測では、APIは400(クライアントによる)と500(サーバーによる)を区別するためにこれを行っています。構文上のエラーを示すために400を使用することは許容できますか、それとも正しくありませんか?許容できる場合、400の使用目的についてより多くの洞察を提供するRFC 2616の注釈付きリファレンスはありますか?

例:

4

8 に答える 8

65

ステータス422(RFC 4918、セクション11.2)が思い浮かびます。

422(処理不能エンティティ)ステータスコードは、サーバーがリクエストエンティティのコンテンツタイプを理解し(したがって、415(サポートされていないメディアタイプ)ステータスコードが不適切)、リクエストエンティティの構文が正しいことを意味します(したがって、400(不正なリクエスト) )ステータスコードは不適切です)が、含まれている命令を処理できませんでした。たとえば、このエラー状態は、XML要求本文に整形式(つまり、構文的に正しい)であるが、意味的に誤ったXML命令が含まれている場合に発生する可能性があります。

于 2011-01-24T19:12:48.650 に答える
19

現時点で、RFC 2616を置き換えて廃止することを目的とした、 HTTPbis仕様の最新ドラフトは次のように述べています

400(Bad Request)ステータスコードは、受信した構文が無効であるか、無意味であるか、サーバーが処理しようとしているものに対する制限を超えているため、サーバーが要求を処理できないか、処理しないことを示します。

この定義は、もちろん変更される可能性がありますが、400で論理エラーに応答するという広く使用されている慣行を承認します。

于 2013-06-25T09:21:00.563 に答える
6

HTTPbisは、論理エラーもカバーするように、400BadRequestの言い回しに対処します。したがって、400には422が組み込まれます。

https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1から
"クライアントエラー(例: 、不正な形式の構文)」

于 2012-10-15T08:21:32.000 に答える
2

HTTPレベル(要求行、ヘッダーなど)での実際の要求が構文的に有効であっても、要求に誤ったデータが含まれていると構文エラーになると主張することができます。

たとえば、Restful WebサービスがカスタムXMLコンテンツタイプのPOSTを受け入れるように文書化されていて、application/vnd.example.com.widget+xml代わりにぎこちないプレーンテキストまたはバイナリファイルを送信する場合、それを構文エラーとして扱うのは合理的であるように思われます-リクエストの本文はそうではありません期待される形で。

これをバックアップするための公式の参照はありませんが、いつものように、RFC2616の解釈にかかっているようです。

更新:RFC7231§6.5.1の改訂された文言に注意してください:

400(Bad Request)ステータスコードは、クライアントエラーと見なされるもの(たとえば、不正な形式の要求構文、無効な要求メッセージフレーミング、または欺瞞的な要求ルーティング)が原因で、サーバーが要求を処理できない、または処理しないことを示します。

この議論は、現在廃止されているRFC2616§10.4.1よりも多くサポートされているようです。

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

于 2011-01-24T18:31:11.943 に答える
2

論理エラーを表すためにも400を使用していますが、この場合、仕様の読み取り方法が原因で400を返すのは間違っていると言わざるを得ません。これが私がそう思う理由です。論理的なエラーは、別のエンティティとの関係が失敗しているか、満たされていないことであり、他のエンティティに変更を加えると、後で同じものが渡される可能性があります。その従業員が存在しないときに(完全に架空の)部門のメンバーとしてその従業員を追加しようとするようなものです(論理エラー)。従業員が存在しないため、メンバー要求としての従業員の追加が失敗する可能性があります。ただし、従業員がシステムに追加された後でも、まったく同じ要求が渡される可能性があります。

ちょうど私の2セント...私たちは最近RFCの言語を解釈するために弁護士と裁判官を必要としています:)

ありがとう、ヴィッシュ

于 2011-01-24T19:16:44.120 に答える
1

Java EEサーバーでは、URLが存在しない「web-application」を参照している場合、400が返されます。それは「構文エラー」ですか?構文エラーの意味によって異なります。はいと思います。

英語の構文規則では、品詞間の特定の関係が規定されています。たとえば、「Bob marries Mary」は、{名詞+動詞+名詞}のパターンに従うため、構文的に正しいです。「ボブ結婚メアリー」は構文的に正しくありませんが、{名詞+名詞+名詞}。

単純なURLの構文は{プロトコル+:+ // +サーバー+:+ポート}です。これによると、「http://www.google.com:80」は構文的に正しいです。

しかし、「abc://www.google.com:80」はどうですか?まったく同じパターンに従っているようです。しかし、実際には構文エラーです。なんで?'abc'はDEFINEDプロトコルではないためです。

重要なのは、400の状況にあるかどうかを判断するには、文字、スペース、および区切り文字を解析する以上のことが必要になるということです。また、有効な「品詞」が何であるかを認識する必要があります。

于 2013-08-29T20:42:47.040 に答える
1

これは難しいです。

私たちはすべきだと思います。

  1. クライアントがリクエスト、ヘッダー、または本文に変更を加える権限を持っている場合にのみ4xxエラーを返します。これにより、リクエストは同じインテントで成功します。

  2. 予期されたミューテーションが発生しなかった場合、つまりDELETEが発生しなかった場合、またはPUTが何も変更しなかった場合に、エラー範囲コードを返します。ただし、POSTは、新しい場所でリソースを作成するか、ペイロードを処理するために使用する必要があると仕様に記載されているため、より興味深いものです。

Vishの回答の例を使用すると、要求が従業員Priyaをマーケティング部門に追加することを意図しているが、Priyaが見つからないか、彼女のアカウントがアーカイブされている場合、これはアプリケーションエラーです。

リクエストは正常に機能し、アプリケーションルールに到達し、クライアントはすべてを適切に実行し、ETagが一致しました。

HTTPを使用しているため、リソースの状態に対するリクエストの影響に基づいて応答する必要があります。そしてそれはあなたのAPIデザインに依存します。

おそらくあなたはこれを設計しました。

PUT { updated members list } /marketing/members

成功コードを返すことは、リソースの「置換」が機能したことを示します。リソースのGETは変更を反映しますが、反映しません。

したがって、適切なネガティブHTTPコードを選択する必要があります。これは、コードがアプリケーションではなくHTTPプロトコルを強く対象としているため、注意が必要な部分です。

公式のHTTPコードを読むと、この2つが適切に見えます。

409(競合)ステータスコードは、ターゲットリソースの現在の状態との競合が原因で、要求を完了できなかったことを示します。このコードは、ユーザーが競合を解決してリクエストを再送信できる可能性がある状況で使用されます。サーバーは、ユーザーが競合の原因を認識するのに十分な情報を含むペイロードを生成する必要があります。

500(内部サーバーエラー)ステータスコードは、サーバーが要求を実行できない予期しない状態に遭遇したことを示します。

私たちは伝統的に500を未処理の例外のように考えてきましたが:-/

一貫して適用および設計されている限り、独自のステータスコードを発明することは不合理ではないと思います。

この設計は扱いが簡単です。

PUT { membership add command } /accounts/groups/memberships/instructions/1739119

次に、常に命令の作成に成功するようにAPIを設計できます。これにより、201 CreatedLocationヘッダーが返され、命令に関する問題はその新しいリソース内に保持されます。

POSTは、新しい場所への最後のPUTに似ています。POSTを使用すると、あらゆる種類のメッセージのサーバー処理が可能になり、「アクションは正常に失敗しました」などのデザインが開かれます。

おそらくあなたはすでにこれを行うAPI、ウェブサイトを書いています。支払いフォームをPOSTしましたが、クレジットカード番号が間違っていたため、正常に拒否されました。

POSTを使用すると、拒否メッセージとともに200または201を返すかどうかは、新しいリソースが作成され、別の場所でGETできるかどうかによって異なります。

そうは言っても、おそらくデータフィールドを更新するだけで、必要なPUTが少ないAPIを設計する傾向があります。また、ルールや処理を呼び出すアクションや、予想される失敗の可能性が高いアクションなどは、命令をPOSTするように設計できます。形。

于 2019-01-23T12:45:39.213 に答える
0

私の場合:

content-type設定を間違えたため、400件の悪いリクエストが届きました。コンテンツタイプを変更して、正常に応答を取得できるようにしました。

前(問題):

ClientResponse response = Client.create().resource(requestUrl).queryParam("noOfDates", String.valueOf(limit))
                .header(SecurityConstants.AUTHORIZATION, formatedToken).
header("Content-Type", "\"application/json\"").get(ClientResponse.class);

後(修正済み):

ClientResponse response = Client.create().resource(requestUrl).queryParam("noOfDates", String.valueOf(limit))
                .header(SecurityConstants.AUTHORIZATION, formatedToken).
header("Content-Type", "\"application/x-www-form-urlencoded\"").get(ClientResponse.class);
于 2020-03-05T12:42:35.233 に答える