HTTP POST リクエストに対する正しい応答は何ですか?
-
05-07-2019 - |
質問
POST メソッドについて、W3 仕様には次のように記載されています。
リソースがOrigin Serverに作成されている場合、応答は201(作成)であり、リクエストのステータスを記述し、新しいリソースを参照するエンティティとロケーションヘッダーを含む必要があります(セクション10.4を参照)。
http://www.ietf.org/internet-drafts/draft-ietf-httpbis-p2-semantics-05.txt (セクション8.5)
実際の標準応答は、新しく作成されたリソースにリダイレクトを送信することのようです。
ASP.NET MVC を使用してサイトを構築しており、仕様に従おうとしたため、 ResourceCreatedResult
クラス:
public class ResourceCreatedResult : ActionResult
{
public string Location { get; set; }
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.Clear();
context.HttpContext.Response.StatusCode = 201;
context.HttpContext.Response.ClearHeaders();
context.HttpContext.Response.AddHeader("Location", Location);
}
}
そして、私のアクションは次のようになります。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateNew(string entityStuff)
{
Entity newEntity = new Entity(entityStuff);
IEntityRepository entityRepository = ObjectFactory.GetInstance<IEntityRepository>();
entityRepository.Add(newEntity);
ActionResult result = new ResourceCreatedResult()
{ Location = Url.Action("Show", new { id = newEntity.Id }) };
return result;
}
ただし、IE、Firefox、Chrome はすべて、新しいリソースへのリダイレクトに失敗します。正しい応答の生成を間違えてしまったのでしょうか、それとも Web ブラウザーはこのタイプの応答を予期しておらず、代わりにサーバーに依存してリダイレクト応答を送信しているのでしょうか?
解決
postまたはpost / redirect / getの後にリダイレクトすることは、アプリケーションがユーザーフレンドリーにするために必要なことです。
編集。これは、HTTP仕様を超えています。 POSTの後に単に201を返すと、ブラウザの戻るボタンの動作が悪くなります。
Webサービスリクエスト(ブラウザに応答しない)は標準に完全に準拠し、投稿後にリダイレクトしないことに注意してください。
このように動作します。
-
ブラウザがデータをPOSTします。
-
アプリケーションがデータを検証します。無効な場合は、フォームで応答し、修正してPOSTできるようにします。
-
アプリケーションはリダイレクトで応答します。
-
ブラウザはリダイレクトを取得し、GETを実行します。
-
アプリケーションはGETを見て応答します。
今-ちょっとした! -戻るボタンが機能します。
他のヒント
明確にするために、ブラウザー(Firefox 3やIE8などの最新のブラウザーを含む)は、「ヒントを受け取らない」そして、Locationヘッダーで提供されたURIへのGETリクエストで HTTP 201:Created
レスポンスをフォローアップします。
Locationヘッダーで指定されたURIにブラウザーを移動させる場合は、代わりに HTTP 303:See Other
ステータスを送信する必要があります。
私の解決策は、新しいリソースへのリンクを含む単純なページと、location.replace()を使用したjavascriptリダイレクトを含む「201 Created」で応答することです。
これにより、同じコードがAPIおよびブラウザーリクエストに対して機能し、[戻る]および[更新]ボタンで適切に再生され、古いブラウザーでは正常に低下します。
仕様に記載されているように、応答はリダイレクト付きの HTTP 201 である必要があります (SHOULD)。したがって、ブラウザ ベンダーが正しい答えを実装することは必須ではありません...
30x コードに変更して、正しくリダイレクトされるかどうかを確認する必要があります。そうであれば、それはブラウザの問題です。そうでない場合は、コードに起因する可能性があります (ASP.NET については何も知らないので、コードを「検証」できません)
何かが「作成」された場合にのみカウントされるべきではありません。したがって、アクションへの単純なリダイレクトは本当に十分なはずですか?