Каков правильный ответ на запрос HTTP POST? - PullRequest
29 голосов
/ 07 января 2009

Для метода POST спецификации W3 говорят:

Если ресурс был создан на исходном сервере, ответ ДОЛЖЕН быть 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 не могут перенаправить на новый ресурс. Я испортил правильный ответ или веб-браузеры не ожидают такого ответа, полагаясь на то, что сервер отправляет ответ Redirect?

Ответы [ 5 ]

18 голосов
/ 24 марта 2009

Если говорить прямо, браузеры (включая современные браузеры, такие как Firefox 3 и IE8) не «принимают подсказку» и следуют за ответом HTTP 201: Created с запросом GET на URI, указанный в заголовке Location.

Если вы хотите, чтобы браузеры использовали URI, указанный в заголовке Location, вы должны вместо этого отправить статус HTTP 303: See Other.

14 голосов
/ 07 января 2009

Перенаправление после post или post / redirect / get - это то, что ваше приложение должно делать для удобства использования.

Редактировать . Это выходит за рамки спецификаций HTTP. Если мы просто возвращаем 201 после POST, кнопка возврата браузера плохо работает.

Обратите внимание, что запросы веб-служб (которые НЕ отвечают браузеру) полностью соответствуют стандарту и НЕ перенаправляют после публикации.

Это работает так.

  1. Браузер размещает данные.

  2. Ваша заявка проверяет данные. Если это неверно, вы отвечаете с формой, чтобы они могли исправить это и POST.

  3. Ваше приложение отвечает перенаправлением.

  4. Браузер получает перенаправление и выполняет GET.

  5. Ваше приложение видит GET и отвечает.

Теперь - эй престо! - кнопка возврата работает.

6 голосов
/ 27 августа 2009

Мое решение состоит в том, чтобы ответить сообщением «201 Created», содержащим простую страницу со ссылкой на новый ресурс и перенаправлением javascript с помощью location.replace ().

Это позволяет одному и тому же коду работать с запросами API и браузера, прекрасно воспроизводится с помощью кнопок «Назад» и «Обновить» и изящно ухудшается в старых браузерах.

1 голос
/ 07 января 2009

Как указано в спецификации, ответ ДОЛЖЕН быть HTTP 201 с перенаправлением. Поэтому поставщику браузера не обязательно внедрять правильный ответ ...

Вы должны попытаться изменить код 30x, чтобы увидеть, правильно ли он перенаправлен. Если это так, то это проблема браузера, иначе она может исходить из вашего кода (я ничего не знаю в ASP.NET, поэтому не могу «проверить» ваш код)

0 голосов
/ 27 августа 2009

Разве это не должно учитываться только тогда, когда что-то "создано" и, следовательно, простого переадресации к действию должно быть действительно достаточно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...