web-dev-qa-db-ja.com

HTTP POSTリクエストに対する正しい応答は何ですか?

POSTメソッドの場合、W3仕様は次のように述べています。

Originサーバーでリソースが作成されている場合、応答は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ブラウザーがこのタイプの応答を期待しないで、代わりにサーバーに依存したりしてください。リダイレクト応答を送信しますか?

30
Giraffe

Postまたはpost/redirect/getの後にリダイレクトすることは、ユーザーフレンドリーにするためにアプリケーションが実行する必要があることです。

編集。これは、HTTP仕様を超えています。 POST後に単に201を返すと、ブラウザの戻るボタンの動作がおかしくなります。

Webサービス要求(ブラウザに応答しない)は標準に完全に準拠しており、ポスト後にリダイレクトしないことに注意してください。

それはこのように動作します。

  1. ブラウザはデータをポストします。

  2. アプリケーションはデータを検証します。それが無効な場合は、フォームで応答して、修正してPOSTできるようにします。

  3. アプリケーションはリダイレクトで応答します。

  4. ブラウザはリダイレクトを取得し、GETを実行します。

  5. アプリケーションはGETを確認して応答します。

さてさてプレスト! -戻るボタンが機能します。

14
S.Lott

明確にするために、ブラウザ(Firefox 3やIE8などの最新のブラウザを含む)は「ヒント」を取得せず、Lo​​cationヘッダーで指定されたURIへのGETリクエストでHTTP 201: Created応答を追跡します。

ブラウザがLocationヘッダーで提供されるURIに移動するようにしたい場合は、代わりにHTTP 303: See Otherステータスを送信する必要があります。

18
dthrasher

私の解決策は、新しいリソースへのリンクを含む単純なページと、location.replace()を使用したJavaScriptリダイレクトを含む「201 Created」で応答することです。

これにより、同じコードがAPI要求とブラウザー要求で機能し、[戻る]ボタンと[更新]ボタンを適切に機能させ、古いブラウザーでは適切に機能を低下させます。

6
Greg Inozemtsev

仕様に記載されているように、応答はリダイレクトを伴うHTTP 201である必要があります。したがって、ブラウザベンダーが正しい答えを実装することは必須ではありません...

30xコードに変更して、正しくリダイレ​​クトされるかどうかを確認してください。もしそうなら、それはブラウザの問題です、そうでなければそれはあなたのコードから来るかもしれません(私はASP.NETで何も知らないので私はあなたのコードを「検証」することができません)

1

それは何かが「作成された」ときにのみカウントされるべきではないので、アクションへの単純なリダイレクトで本当に十分であるべきでしょうか?

0
MarkKGreenway