浏览器302重定向传递hash

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器302重定向传递hash相关的知识,希望对你有一定的参考价值。

参考技术A 浏览器和服务器的实现并没有严格遵守HTTP中302的规范,服务器不加遵守的返回302,浏览器即便原请求是post也会自动重定向,导致规范和实现出现了二义性。

所以HTTP 1.1中将302的规范细化成了303和307

继承了HTTP 1.0中302的实现(即原请求是post,也允许自动进行重定向,结果是无论原请求是get还是post,都可以自动进行重定向)。

307则继承了HTTP 1.0中302的规范(即如果原请求是post,则不允许进行自动重定向,结果是post不重定向,get可以自动重定向)。

重定向到action,需要传递数据

【中文标题】重定向到action,需要传递数据【英文标题】:Redirect to action and need to pass data 【发布时间】:2011-03-22 18:53:22 【问题描述】:

我有一个控制器来处理针对我的问题的三个操作。

第一个是编辑操作,它返回一个带有 HTML 表单的视图,用户可以编辑给定项目的属性。

第二个是更新操作,它接受来自浏览器的回发并更新数据库。当更新成功时,我们会重定向到操作。

第三个是显示给定项目细节的显示动作。此操作是我们在成功更新后被重定向到的位置。

流程是:

显示 -> 编辑 -> 更新(成功:y -> 重定向到显示,n -> 返回编辑)

我想要实现的是在更新成功时触发一个标志,以便在下一个显示视图中我可以为用户显示一条确认消息。问题是我不能 100% 确定通过 RedirectToAction() 调用传输数据的最佳方式。有人认为我使用的是查询字符串?我们已经将变量与查询字符串一起用于另一个目的,但我的一部分人对滥用它持怀疑态度。重定向的调用如下。

RouteValueDictionary dict = Foo.GetRouteValues(bar);

RedirectToAction("Show", dict);

我也读过这个问题,但如果我不必使用 TempData 属性,我很担心。

Question

感谢您的建议!

【问题讨论】:

【参考方案1】:

编辑:抱歉,最初没有看到您关于不想使用 TempData 的说明。

简而言之 - 如果客户端刷新/重新加载他们被重定向到的页面,您是否希望您的消息重新出现?

如果你这样做了,那么使用查询字符串,比如:

return(RedirectToAction("Index", new  message = "hi there!" ));

然后定义

public ActionResult Index(string message)  

或显式地取出 Request.QueryString["message"] 并以通常的方式通过 ViewData 将其传递给 View。这也适用于不接受来自您网站的 cookie 的浏览器。

如果您不想再次显示该消息,那么 ASP.NET MVC 1.0 会为此目的提供 TempData 集合。

TempData 属性值存储在会话状态中,直到 来自同一浏览器的下一个请求,之后它们被清除 - 因此,如果您在返回 RedirectToAction 之前立即将某些内容放入 TempData,它将可用在重定向的结果上,但之后会立即被清除。

下面是对 ASP.NET MVC 启动项目中 HomeController 的简单改动:

public ActionResult Index() 
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    return View();


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string submitButton) 
    TempData["message"] = "You clicked " + submitButton;
return(RedirectToAction("Index"));


public ActionResult About() 
    return View();

相应的视图 /Views/Home/Index.aspx 应该包含如下内容:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
  <% if (TempData["message"] != null)  %>
    <p><%= Html.Encode(TempData["message"]) %></p>
  <%  %>
  <% using (Html.BeginForm())  %>
    <input type="submit" name="submitButton" value="Button One" />
    <input type="submit" name="submitButton" value="Button Two" />
  <%  %>
</asp:Content>

您会注意到在 POST-REDIRECT-GET 序列之后立即显示 TempData 消息,但如果您刷新页面,它将不会再次显示。

请注意,此行为在 ASP.NET MVC 2 中已更改 - 有关详细信息,请参阅 this article 中的“在操作方法之间传递状态”。

【讨论】:

感谢您的精彩解释。由于我们在 2.0,我将看一下这篇文章。我在帖子中提到我想远离 TempData 属性,但是如果这是事实上的方式,那么它可能不会那么糟糕。再次感谢。 这是一个老问题,但现在链接已断开:( 那篇文章的现代(ish)工作链接(向下滚动大约一半):msdn.microsoft.com/en-us/library/dd394711(v=vs.100).aspx【参考方案2】:

也不是TempData 的粉丝,另外我不想在 URL 中传递成功标志,因为我不想看到

应用/设置?saveSuccess=true

在浏览器的 URL 栏中。

我的解决方案使用临时 cookie:

[HttpPost]
public ActionResult Settings(SettingsViewModel view)

    if (ModelState.IsValid)
    
        //save
        Response.SetCookie(new HttpCookie("SettingsSaveSuccess", ""));
        return RedirectToAction("Settings");
    
    else
    
        return View(view);
         

并在相应的 Get 操作中检查此 Cookie 的存在并将其删除:

[HttpGet]
public ActionResult Settings()

    var view = new SettingsViewModel();
    //fetch from db and do your mapping
    bool saveSuccess = false;
    if (Request.Cookies["SettingsSaveSuccess"] != null)
    
        Response.SetCookie(new HttpCookie("SettingsSaveSuccess", "")  Expires = DateTime.Now.AddDays(-1) );
        saveSuccess = true;
    
    view.SaveSuccess = saveSuccess;
    return View(view);

nb 如果你开始传递比布尔标志更复杂的东西,这可能是一个相当滑的斜坡

【讨论】:

嗨 - 如果您将作为确认消息的字符串传递给 cookie 值会有什么危险(例如,您的设置保存正常,或设置未保存)? @Bartosz 你能只使用一个布尔值,然后根据它设置响应消息吗?如果响应消息可能超过 2 件事,那么您将不得不务实 - 感觉有点不对 - 即,如果您有多个错误消息,那么它应该在重定向之前显示 - 如果您的设置没有保存,那么应该由代码的第一个 sn-p 中的 else 语句处理,不应重定向

以上是关于浏览器302重定向传递hash的主要内容,如果未能解决你的问题,请参考以下文章

301/302,文档正文显示“如果您的浏览器没有重定向您,请单击此处”锚点

如何找到 301/302 重定向源?

处理 http 302 重定向响应

301,302,303,307重定向区别

如何使用转发 URL 执行 302 重定向

防止 Spring Security 在登录/注销后进行 302 重定向