【问题标题】:Prevent form resubmit by back button + refresh/retry防止通过后退按钮重新提交表单+刷新/重试
【发布时间】:2015-12-30 02:29:00
【问题描述】:

如果已经有人问过这个问题,我深表歉意,但我已经进行了大量搜索,但还没有找到与我相似的问题。

在我的应用程序中,我有一个密码更改页面,如果某人是新用户或重置了他/她的密码,则会触发该页面。

问题是,一旦用户进行更改并点击提交,他/她就会被重定向到主页。现在,如果用户多次发送后退按钮以进入密码更改页面,他们会遇到一个过期的页面,他们可以点击刷新。然后浏览器要求用户重试提交数据。这个提交请求是一个 POST 并且可以在数据包中看到用户之前输入的原始数据。

到目前为止,我只能在 IE 上复制此问题。在 FF 和 Chrome 上尝试过,但没有。

我的问题是,有没有办法使用 jQuery、HTML、WSS 或其他方式来防止重新提交此 POST?我最关心的是带有可见数据的数据包。

谢谢。

【问题讨论】:

  • “数据可以看到”是什么意思?你在哪里看到的?
  • 为什么他们在提交原始请求时看不到它?原始和重试有什么区别?
  • 用户可以看到原始表单,点击提交后跳转到主页面。但是他们可以向页面发送几次垃圾邮件,然后单击重试。这会发送一个可以被wireshark 捕获的重复请求。用户仍然出错,他必须重新登录,因为此时会话已过期。但是我想知道如果使用刷新+重试,是否有办法阻止请求消息首先发送。 -- 重试是过期页面,可以重新提交数据。
  • -- 重新提交的数据不会改变任何事情,因为此时会话 ID 无效,但可以将数据视为“安全问题”这一事实......即使它是一个https 连接。
  • 我仍然不明白你所做的区分。如果他们可以使用wireshark捕获重复请求,为什么他们不能同时捕获原始请求?

标签: javascript jquery html progress-4gl webspeed


【解决方案1】:

此类问题的一个非常通用的解决方案是 Post/Redirect/Get-pattern。

这意味着,当您想要对在后台更新某些内容的页面进行 POST 时,您实际上会创建两个目标页面:

第 1 页

POST 的目标页面。包含用于更新数据库/文件系统/API 或任何需要完成的逻辑。这只是一个没有任何真实视觉反馈的 URL,而是在逻辑完成后将您重定向到第 2 页(见下文)。重定向是一个简单的 GET 而不是 POST。

第 2 页

显示您对“第 1 页”操作的反馈的页面。可能只是一条消息“密码更新OK”或来自数据库的实际数据或任何适合您的东西。

现在,当有人使用您的表单时,他们会被发布到将执行后台操作的第 1 页,然后他们被重定向到第 2 页。

现在,如果他们重新加载,他们不会重做整个逻辑部分,而只会重做反馈部分。

维基百科对此有很好的解释:

https://en.wikipedia.org/wiki/Post/Redirect/Get

如何在 Progress WebSpeed 中进行重定向

在您的 outputHeader-procedure 或您所做的任何地方

output-content-type ("text/html":U).

如果 output-content-type: 先做你的逻辑,然后插入这样的东西:

OUTPUT-HTTP-HEADER("Status", "301").
OUTPUT-HTTP-HEADER("Location","http://www.yoursite.com/newurl").
OUTPUT-HTTP-HEADER("","").

现在,一旦逻辑处理完毕,您将被重定向到服务器端。如果需要,您还可以在 url 中插入参数:

DEFINE VARIABLE iId as INTEGER NO-UNDO.
OUTPUT-HTTP-HEADER("Status", "301").
OUTPUT-HTTP-HEADER("Location","http://www.yoursite.com/newurl?id=" + STRING(iId)).
OUTPUT-HTTP-HEADER("","").

【讨论】:

  • 这对我不起作用,因为最初的问题是第二个帖子有我不想被捕获的数据。此 PRG 方法目前也在应用程序中使用。
  • 重定向是如何完成的?适当的 301 或其他类似 javascript/meta-tags 的东西?
  • WSS 过程中的Javascript
  • 如果您将其更改为正确的重定向,您可能会解决问题,我将在上面的答案中插入一些代码。
  • 相同的结果,POST 请求不会用数据查询服务器,但它仍然在wireshark 中显示为一个数据包。我认为没有办法阻止请求重新发送如果用户单击重试,则从缓存中。至少不是我们的应用程序的实现方式.. 不过感谢您的建议。
猜你喜欢
  • 2017-12-13
  • 1970-01-01
  • 2018-02-21
  • 2011-12-06
  • 1970-01-01
  • 2012-07-07
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
相关资源
最近更新 更多