对于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都无法重定向到新资源。我是否搞砸了生成正确的响应,或者网络浏览器不期望这种类型的响应,而是依靠服务器发送重定向响应?

有帮助吗?

解决方案

在帖子或帖子/重定向/获取后重定向是您的应用程序必须做的事情才能使用户友好。

修改即可。这超出了HTTP规范。如果我们在POST后返回201,则浏览器后退按钮表现不佳。

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

就像这样。

  1. 浏览器发布数据。

  2. 您的应用程序会验证数据。如果它无效,您可以回复表单,以便他们可以修复它并发布POST。

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

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

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

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

其他提示

明确地说,浏览器(包括像Firefox 3和IE8这样的现代浏览器)不会“提示”。并使用对Location头中提供的URI的GET请求跟进 HTTP 201:Created 响应。

如果您希望浏览器转到Location标头中提供的URI,则应发送 HTTP 303:请参阅其他状态。

我的解决方案是回复一个'201 Created',其中包含一个带有新资源链接的简单页面,以及一个使用location.replace()的javascript重定向。

这使得相同的代码可以用于API和浏览器请求,可以很好地使用“后退”和“刷新”按钮,并在旧浏览器中正常降级。

如规范中所述,响应应该是带有重定向的HTTP 201。因此,浏览器供应商不一定要实现正确的答案......

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

不应该只计算什么时候“创建”的东西。因此,简单的重定向行动应该真的足够吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top