8

いくつかの (django) 単体テストのデバッグに 20 分を費やしました。私はビュー POST をテストしていましたが、302 リターン コードが返されることを期待していました。その後、多数のデータベース エンティティが期待どおりであると断言しました。最近マージされたコミットによって新しいフォーム フィールドが追加され、正しいフォーム データが含まれていなかったため、テストが失敗していたことが判明しました。

問題は、HTTP リターン コードが 302 ではなく 200 だったためにテストが失敗したことです。この問題を解決するには、応答 HTTP を出力してそれを調べるしかありませんでした。問題を解決するために HTML に目を通さなければならないという苛立ちはさておき、200 は、処理されない POST の間違ったコードのように思えます。4xx (クライアント エラー) の方が適切と思われます。さらに、応答コードが問題を直接指摘してくれるので、テストのデバッグが簡単になります。

REST API 内の戻りコードとして 422 (Unprocessable Entity) を使用することについて読んだことがありますが、HTML ビュー / ハンドラー内でそれを使用している証拠が見つかりません。

私の質問は - 他の誰かがこれを行っていますか? そうでない場合は、なぜですか?

[更新1 ]

明確にするために、この質問は API ではなく HTML フォームに関するものです。

Djangoではなく、HTTP応答コード自体に関する質問でもあります。それはたまたま私が使っているものです。django タグを削除しました。

[更新2 ]

W3C 参照 ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html )を使用して、さらに明確にします。

10.2 成功した 2xx

このクラスのステータス コードは、クライアントの要求が正常に受信され、理解され、受け入れられたことを示します。

10.4 クライアント エラー 4xx

ステータス コードの 4xx クラスは、クライアントがエラーを起こしたと思われる場合を対象としています。

10.4.1 400 不正な要求

構文が正しくないため、サーバーは要求を理解できませんでした。

そしてhttps://www.rfc-editor.org/rfc/rfc4918#page-78から

11.2. 422 処理不能エンティティ

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

[更新 3 ]

掘り下げてみると、422 は WebDAV 拡張機能 [1] であり、これがその不明瞭さを説明している可能性があります。とはいえ、Twitter は独自の目的で 420 を使用しているため、私は好きなようにすると思います。しかし、それは4から始まります。

[更新 4 ]

HTTP 1.1 仕様 ( https://www.rfc-editor.org/rfc/rfc2616#section-6.1.1 )からの、カスタム応答コードの使用、およびそれらの処理方法 (認識されない場合) に関する注意事項:

HTTP ステータス コードは拡張可能です。HTTP アプリケーションは、登録されたすべてのステータス コードの意味を理解する必要はありませんが、そのような理解が望ましいことは明らかです。ただし、アプリケーションは、最初の数字で示されるステータス コードのクラスを理解する必要があり、認識されない応答をキャッシュしてはならないことを除いて、そのクラスの x00 ステータス コードと同等であるとして認識されない応答を処理する必要があります。たとえば、認識できないステータス コード 431 がクライアントによって受信された場合、クライアントは、その要求に問題があったと安全に想定し、400 ステータス コードを受信したかのように応答を処理できます。このような場合、ユーザー エージェントは、応答で返されたエンティティをユーザーに提示する必要があります。これは、そのエンティティには、異常な状態を説明する人間が読み取れる情報が含まれている可能性が高いためです。

[1] https://www.rfc-editor.org/rfc/rfc4918

4

4 に答える 4

2

一部のフォーム POST リクエストで 4xx HTTP エラーが発生することは明らかですが (URL が間違っている、必要なフィールドがない、認証 Cookie の送信に失敗するなど)、パスワードの入力ミスや必須フィールドの誤った省略は、アプリケーションで非常によくあることであり、予想されることです。

すべてのフォーム無効化の問題が HTTP エラーを構成する必要があることは、どの仕様からも明らかではないようです。

私の直感では、サーバーがクライアントにフォームを送信し、クライアントが期待されるすべてのフィールドを含む正しい形式の POST 要求でそのフォームに即座に応答する場合、一般的なビジネス ロジック違反は HTTP エラーではないはずです。

クライアント側のスクリプトが転送メカニズムとして HTTP を使用している場合、状況はさらに明確ではないように見えます。たとえば、JSON-RPC リクエストがフォームの詳細を送信する場合、サーバー側の関数が正常に呼び出され、呼び出し元に返される応答は 200 成功のように見えます。

逸話: 不正な資格情報でログインすると、Facebook、Google、および Wikipedia から 200 が返され、Amazon から 204 が返されます。

理想的には、IETF は RFC でこれを解決し、「フォームの無効化の失敗により操作が実行されませんでした」という HTTP エラー コードを追加するか、これをカバーするために 422 の定義を拡張します。

于 2016-05-20T21:38:02.983 に答える
2

結果が成功しない場合、200 が間違っているというあなたの意見は正しいです。

また、結果ページへのリダイレクトによる成功は、302 ではなく 303 であるべきだとも主張します。

クライアント エラーの場合は 4xx が正しいです。422は私には正しいようです。いずれにせよ、IANA に登録せずに新しい 4xx コードを発明しないでください。

于 2013-03-27T16:12:04.883 に答える
1

正直なところ、少し驚くべきことですが、受け入れられた答えはないようです。フォーム検証は Web 開発の基礎であるため、検証の失敗を示す応答コードがないという事実は、機会を逃したように思えます。特に、自動テストの普及を考えると。応答コードをテストするだけでなく、エラー メッセージの HTML コンテンツを調べて応答をテストするのは現実的ではないようです。

200 はビジネス ルールに違反する要求に対する間違った応答コードであり、302 も不適切であるという質問に対する私の主張に固執します。(フォームが検証に失敗した場合、サーバー上の状態は更新されていないはずです。したがって、べき等であり、ユーザーがフォームを再送信するのを防ぐために PRG パターンを使用する必要はありません。許可してください。)

したがって、「承認された」メソッドがないため、現在、独自の 421 で (文字通り) テストしています。非標準の HTTP ステータス コードの使用で問題が発生した場合は、報告します。

この回答に更新がない場合は、本番環境で使用しており、機能しており、同じことができます。

于 2013-03-27T14:41:07.080 に答える
-1

リダイレクトしない場合、POSTは200を返します。302はPOSTリクエスト後にヘッダーで自動的に送信されないため、ヘッダー(https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpResponse)を手動で送信する必要があります。コードはフォームのデータを中継しません。

コード302を使用してフォーム(またはその他)にリダイレクトする理由は、ブラウザが更新または履歴の参照時にデータを繰り返し送信できないようにするためです。

于 2013-03-22T22:51:33.170 に答える