Session 如何在发布后向用户显示消息+;HTTP重定向

Session 如何在发布后向用户显示消息+;HTTP重定向,session,redirect,user-interface,error-handling,post-redirect-get,Session,Redirect,User Interface,Error Handling,Post Redirect Get,我使用的是避免多次提交表单。但是,它有一个严重的缺点-您不能简单地将确认消息回送给用户(显然,用户将看不到该页面,他将被重定向到另一个页面) 这个问题的解决方案是什么?我认识其中两个,但似乎没有一个是完美的 使用自定义重定向URL,如:http://example.com/?msg=data-已保存。它是无状态的,所以我认为它相当可靠。但当用户复制链接、为其添加书签等时,就会产生问题 存储会话变量/cookie,并在每次页面加载时检查它。如果已设置,请清除它并显示消息。这似乎还可以,但我不确定

我使用的是避免多次提交表单。但是,它有一个严重的缺点-您不能简单地
将确认消息回送给用户(显然,用户将看不到该页面,他将被重定向到另一个页面)

这个问题的解决方案是什么?我认识其中两个,但似乎没有一个是完美的

  • 使用自定义重定向URL,如:
    http://example.com/?msg=data-已保存
    。它是无状态的,所以我认为它相当可靠。但当用户复制链接、为其添加书签等时,就会产生问题
  • 存储会话变量/cookie,并在每次页面加载时检查它。如果已设置,请清除它并显示消息。这似乎还可以,但我不确定这一点-它强烈依赖于饼干,它有点复杂
或者也许还有其他我不知道的方法?会话和URL参数的某种组合?我不知道


你认为最好的方法是什么?哪一个缺点最少?利与弊是什么?

我使用会话变量方法。我真的不喜欢在URL中嵌入显示错误消息,尤其是您注意到的URL保存/共享问题,我喜欢如果用户重新加载目标页面,它将是一个干净的实例。

这取决于您运行的平台

RubyonRails调用此flash[:notice]=“您的操作已执行”,ASP.NETMVC调用此TempData[“notice”]=“您的操作已执行”


基本上,它们只在HttpSession中存储一次往返的数据。通过这种方式,您可以在另一个web请求上检索数据。

还有几个其他堆栈溢出问题涉及到这一点,尽管我认为没有人能如此清楚地总结这个问题。以下是一些:

  • 这两种方法都可以解决这个问题,讨论值得一读
大多数方便的解决方案都是基于会话的,或者有更严重的缺点(例如将消息嵌入查询字符串)


如果不能保证会有会话,另一种(相当昂贵的)方法是根据表单提交的结果重定向到不同的视图。例如,您可以重定向到
EditWidgetView
EditWidgetSaveSuccessfulView
,或者
EditWidgetSaveErrorView
(或者您只是在出现错误时不重定向)。在某些语言和框架中,这是不切实际的,甚至会让你完全放弃显示确认/错误消息,但在其他语言和框架中,这可能是值得的。

几乎所有允许用户登录的网站都是依靠cookie登录的。这不是一个完美的解决方案,但这是我们最好的解决方案


此外,会话处理是web开发框架通常为您处理的事情之一。

如果您不想出于任何原因依赖会话,您可以使用Get变量/自定义url,如果该变量存在,请检查“引用”。如果参考正确,则显示消息。是的,这增加了对为了显示确认消息而发送的引用的依赖,但除此之外,您依赖的是会话(会话虽然可靠,但也不是所有解决方案都100%完美)


老实说,一些通常对这类事情很在行的大型网站只是在url中粘贴了一个“actiondone=true”。(我注意到Facebook在某些地方这样做。)

这次讨论来得很晚

您可以结合使用两个建议的选项

在POST请求之后,客户端被重定向(303)到一个URL,该URL指示可能存在针对该请求的响应消息:

Client: GET  http://example.com/foo.cgi
Server: 200  Ok

Client: POST http://example.com/bar.cgi
Server: 303  http://example.com/foo.cgi?msg=true
如果
msg
参数为
true
,则会在会话中查找消息,并(如果找到)包含在对客户端的响应中。
如果
msg
参数为
!如果为true(或不存在),则跳过查找步骤

使用此解决方案,可以防止在URL中显示实际消息,URL仅指示可能存在消息。此外,消息仅在需要时显示(=在会话中找到时)


另一个优点是,此解决方案还允许在HTTP响应中包含适当的现金控制。

换句话说,框架通常会采纳您的第二个建议,即使用链接到cookie的会话数据存储。您可以通过检查会话数据中是否存在消息来实现这一点(每次请求后都会清除该消息)。这里不需要_GET参数……您可以,但是您会阻止浏览器缓存资源+1,因为我也在考虑使用“Referer”[sic]选项;-)