Каков правильный ответ на запрос HTTP POST?
Для метода 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 не могут перенаправляться на новый ресурс. Я перепутал, генерируя правильный ответ, или веб-браузеры не ожидают такого типа ответа, вместо этого полагаясь на серверы для отправки ответа на перенаправление?
Ответы
Ответ 1
Перенаправление после публикации или отправки/перенаправления/получения - это то, что ваше приложение должно сделать удобным для пользователя.
Edit. Это выше и выше спецификаций HTTP. Если мы просто возвращаем 201 после POST, кнопка назад браузера ведет себя плохо.
Обратите внимание, что запросы веб-служб (которые НЕ отвечают на браузер) полностью соответствуют стандарту и НЕ перенаправляют после публикации.
Он работает следующим образом.
-
Браузер выполняет отправку данных.
-
Ваше приложение проверяет данные. Если он недействителен, вы отвечаете формой, чтобы они могли исправить его и POST.
-
Ваше приложение отвечает перенаправлением.
-
Браузер получает перенаправление и выполняет GET.
-
Ваше приложение видит GET и отвечает.
Теперь - эй престо! - работает кнопка "Назад".
Ответ 2
Чтобы быть явным, браузеры (включая современные браузеры, такие как Firefox 3 и IE8) не "принимают подсказку" и отслеживают ответ HTTP 201: Created
с запросом GET на URI, представленный в заголовке Location.
Если вы хотите, чтобы браузеры переходили в URI, указанный в заголовке Location, вы должны отправить статус HTTP 303: See Other
.
Ответ 3
Мое решение - ответить "Создано 201", содержащее простую страницу со ссылкой на новый ресурс и перенаправление javascript с использованием location.replace().
Это позволяет работать с одним и тем же кодом для запросов API и браузера, отлично играет с кнопками Back и Refresh и изящно изнашивается в старых браузерах.
Ответ 4
Как указано в спецификации, ответ ДОЛЖЕН быть HTTP 201 с перенаправлением. Поэтому не обязательно, чтобы поставщик браузера выполнял правильный ответ...
Вам следует попробовать перейти на 30-кратный код, чтобы узнать, правильно ли он перенаправлен. Если это так, это проблема с браузером, иначе это может произойти из вашего кода (я ничего не знаю в ASP.NET, поэтому я не могу "проверить" ваш код)
Ответ 5
Не следует ли рассчитывать только, когда что-то "создано", и поэтому простое перенаправление на действие должно быть действительно достаточным?