我正在使用 PRG模式 以避免多次提交表单。然而,它有一个严重的缺点——你不能简单地 echo 给用户的确认消息(显然,用户不会看到该页面,他将被重定向到另一个页面)。

解决这个问题的方法有哪些?我认识其中两个,但他们似乎都不完美。

  • 使用自定义重定向 URL,例如: http://example.com/?msg=data-saved. 。它是无状态的,所以我认为它是相当可靠的。但当用户复制链接、为其添加书签等时,它会产生问题。
  • 存储会话变量/cookie,并在每次页面加载时检查它。如果已设置,请将其清除并显示消息。看起来不错,但我不确定这个——它强烈依赖 cookie,有点复杂。

或者也许还有其他我不知道的方法?会话和 URL 参数的某种组合?不知道。

您认为最好的方法是什么?哪一个的缺点最少?优缺点都有什么?

有帮助吗?

解决方案

几乎每个允许用户登录的网站都是依靠 cookie 来实现的。这不是一个完美的解决方案,但它是我们得到的最好的解决方案。

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

其他提示

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

大多数方便的解决方案都是基于会话的或具有更严重的缺点(例如将消息嵌入查询字符串中)。

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

如果您出于某种原因不想依赖会话,您可以使用 Get 变量/自定义 url,然后如果该变量存在,请检查引用。如果引用正确,则显示该消息。是的,这增加了对发送引用以显示确认消息的依赖,但除此之外,您还要依赖会话(会话虽然可靠,但也不是 100% 适合所有解决方案。)

老实说,一些通常对此类事情非常擅长的大型网站只是在网址中添加“actiondone=true”。(我注意到 Facebook 在某些地方这样做了。)

这取决于您运行的平台。

Ruby on Rails 调用此 flash[:notice] = "您的操作已执行",ASP.NET MVC 调用此 TempData["notice"] = "您的操作已执行"...

基本上,它们只是将数据存储在 HttpSession 中,仅用于单次往返。这样您就可以检索另一个 Web 请求上的数据。

这次讨论来得很晚..

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

在 POST 请求之后,客户端被重定向 (303) 到一个 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 响应中包含适当的现金控制。

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

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