30

对于 POST 方法,W3 规范说:

如果在源服务器上创建了资源,则响应应该是 201(已创建)并包含描述请求状态并引用新资源的实体和 Location 标头(参见第 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 都无法重定向到新资源。我是否搞砸了生成正确的响应,或者网络浏览器不期望这种类型的响应,而是依靠服务器发送重定向响应?

4

5 回答 5

18

HTTP 201: Created明确地说,浏览器(包括 Firefox 3 和 IE8 等现代浏览器)不会“接受提示”,而是通过对 Location 标头中提供的 URI 的 GET 请求来跟进响应。

如果您希望浏览器转到 Location 标头中提供的 URI,则应HTTP 303: See Other改为发送状态。

于 2009-03-24T13:01:57.460 回答
15

发布后重定向或发布/重定向/获取是您的应用程序必须做的事情以使用户友好。

编辑. 这超出了 HTTP 规范。如果我们在 POST 后简单地返回 201,浏览器后退按钮的行为就会很糟糕。

请注意,Web 服务请求(不响应浏览器)完全遵循标准,并且不会在发布后重定向。

它是这样工作的。

  1. 浏览器发布数据。

  2. 您的应用程序验证数据。如果它是无效的,你用表单来回复,这样他们就可以修复它并发布。

  3. 您的应用程序以重定向响应。

  4. 浏览器获取重定向并执行 GET。

  5. 您的应用程序看到 GET 并做出响应。

现在 - 嘿presto!-- 后退按钮有效。

于 2009-01-07T12:52:44.153 回答
6

我的解决方案是响应“201 Created”,其中包含一个简单页面,其中包含指向新资源的链接,以及使用 location.replace() 的 javascript 重定向。

这使得相同的代码可以用于 API 和浏览器请求,可以很好地使用 Back 和 Refresh 按钮,并在旧浏览器中优雅地降级。

于 2009-08-27T04:42:03.003 回答
1

如规范中所述,响应应该是带有重定向的 HTTP 201。因此,浏览器供应商不必强制执行正确的答案......

您应该尝试更改为 30x 代码以查看它是否被正确重定向。如果是这样,这是一个浏览器问题,否则它可能来自您的代码(我不知道 ASP.NET 中的任何内容,所以我无法“验证”您的代码)

于 2009-01-07T13:25:41.017 回答
0

难道这不应该只在“创建”某些东西时才算,因此一个简单的重定向到行动应该就足够了吗?

于 2009-08-27T04:57:59.087 回答