如何停止“重新提交”和“刷新”button以重新提交表单?
我正在做网页开发。
我有一个页面做的信用卡,当用户点击“刷新”或“返回”,交易将被执行一次,这是不需要的。
这包括浏览器左上angular的“返回”和“刷新”button,“右键 – >刷新/返回”,按“F5”键。 这只能在某些cgi页面上完成,而不是全部。
这可以使用Javascript来完成吗? 或者其他方法?
标准的方法是分三步完成。
- 表单页面将字段提交到处理页面
- 处理页面处理数据并redirect到结果页面
- 结果页面只显示结果,重新加载不会造成任何伤害。
这打破了基本的浏览器用户体验模型…用户应该始终能够在浏览器中使用“刷新”和“返回”button。 build议您以另一种方式修复您的页面。
如果你更新你的问题来包含你正在使用的服务器语言/平台/技术,那么有人可能会提出一个解决scheme。
重新提交表单的简单事实会产生重复的事务,这令人担忧。 您应该进行一些检查以确保每次提交表单数据都是唯一的。
例如,提交表单的页面应该被赋予一个与表单一起提交的唯一ID。 业务逻辑应该能够认识到提交的表单已经被处理了(因为(不再)唯一的ID将是相同的),所以忽略了第二次尝试。
“标准的方式”仍然不会阻止客户两次点击后退button,甚至退回并重新提交表单,如果他们不认为(无论是什么原因)它已被处理。
-
生成一个随机的string并将其存储在会话中,
-
然后将其作为隐藏值输出到您的表单中,
-
检查提交和存储variables,如果匹配处理您的请求,
-
去1。
将此代码放置在表单页面上
Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetExpires(DateTime.Now-new TimeSpan(1,0,0)); Response.Cache.SetLastModified(DateTime.Now); Response.Cache.SetAllowResponseInBrowserHistory(false);
你不应该试图“阻止”这些行为。 你应该做的是确保没有什么事情发生时,有人“双重提交”的forms。
而在某些浏览器中,你甚至不能这样做,这很好!
最好的方法是拥有足够的会话处理逻辑,以便您可以将第二次(和之后)的尝试识别为“这只是重新提交”并忽略它。
我没有看到这里,所以在这里。
- 在表单中添加一个唯一的标记。
- 提交button触发一个xmlhttp(ajax)请求到服务器,以创build一个以存储值为1的令牌命名的会话variables。
- ajax请求在接收到状态改变后提交表单。
- 表单处理脚本检查存储的值为1的会话variables。
- 该脚本删除会话variables并处理表单。
如果没有find会话variables,表单将不会被处理。 由于该variables一旦find就被删除,只能通过按下提交button来运行该表单。 刷新后不会提交表格。 这将工作,而不使用redirect。
vartec:s解决scheme解决了重装问题,而不是后端问题,所以这里有一个解决scheme:
- 表单页面设置会话variables,例如session(“fromformpage”)= 1
- 处理页面检查会话variables,如果它的=“1”然后处理数据,并redirect到结果页面,如果不是=“1”,那么只是redirect到结果页面。
- 结果页面将会话variables设置为“”。
然后,如果用户正在按回button,则处理页面将不再执行该处理,只redirect到处理页面。
我发现上面的post/redirect/得到解释有点模棱两可
这就是我所遵循的,希望能在将来帮助别人
http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html
基本上,基于上述解决scheme的过程是:
- 从FORM页面提交到处理页面(或自己)
- 处理数据库或支付处理等
- 如果需要,将用户反馈消息存储在会话variables中,可能的错误消息等
- 执行标题redirect到结果页面(或原始表单页面)。 如果需要,显示来自处理页面的自定义消息。 如“错误信用卡付款被拒绝” ,并重置会话variables。
redirect类似于:
header("HTTP/1.1 303 See Other"); header("Location: http://$_SERVER[HTTP_HOST]/yourfilehere.php"); die();
标题redirect将在“yourfilehere.php”上启动一个GET
请求,因为redirect只是一个“请求”从服务器获取数据,而不是向服务器提交数据的POST
。 因此,redirect/ GET
可以防止在刷新之后进行任何进一步的DB /支付处理。 301
错误状态将有助于后退button。
有用的阅读:
- http://en.wikipedia.org/wiki/URL_redirection#HTTP_status_codes_3xx
- http://www.theserverside.com/news/1365146/Redirect-After-Post
- http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html
- https://en.wikipedia.org/wiki/HTTP#Request_methods
- http://en.wikipedia.org/wiki/Post/Redirect/Get
只要把这个JavaScript的头部分上面的aspx页的html部分
<script type = "text/javascript" > function disableBackButton() { window.history.forward(); } setTimeout("disableBackButton()", 0); </script>
我们需要把它放在我们希望阻止用户通过点击后退button访问的页面的html部分
完整的页面代码如下所示
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> <script type = "text/javascript" > function disableBackButton() { window.history.forward(); } setTimeout("disableBackButton()", 0); </script> </head> <body onload="disableBackButton()"> <form id="form1" runat="server"> <div> This is First page <br /> <br /> Go to Second page <br /> <br /> <asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="~/Default2.aspx">Go to Second Page </asp:LinkButton></div> </form> </body> </html>
如果你使用的是Firefox,那么使用而不是onload
如果要使用aspx页面后面的代码禁用后退button,则需要在后面提到的代码后面写下C#代码
protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); string strDisAbleBackButton; strDisAbleBackButton = "<script language="javascript">\n"; strDisAbleBackButton += "window.history.forward(1);\n"; strDisAbleBackButton += "\n</script>"; ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "clientScript", strDisAbleBackButton); }
我们也可以通过在Page_load事件或Page_Init事件中写这行代码来禁用浏览器caching或caching
protected void Page_Init(object Sender, EventArgs e) { Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1)); Response.Cache.SetNoStore(); }
这样做,用户在点击浏览器的button时会得到页面已经过期的消息
演示是:
此代码适用于不从当前页面我回来..
在这里,我把一个代码,可以帮助你,而不是打开contextmenu和浏览器重新加载问你离开一个页面或不…
我正在尝试点击浏览器后退button
jQuery( document ).ready(function() { document.onkeydown = fkey; document.onkeypress = fkey document.onkeyup = fkey; var wasPressed = false; function fkey(e){ e = e || window.event; //alert(e.keyCode); if( wasPressed ) return; if (e.keyCode == 116 || e.keyCode == 8 || e.keyCode == 17) { // alert("f5 pressed"); window.onbeforeunload = null; return true; } } window.onbeforeunload = function (event) { var message = ''; // Type message here if (typeof event == 'undefined') { event = window.event; } if (event) { event.returnValue = message; } return message; }; jQuery(function () { jQuery("a").click(function () { window.onbeforeunload = null; }); jQuery(".btn").click(function () { window.onbeforeunload = null; }); //Disable part of page $(document).on("contextmenu",function(e){ return false; }); });});
谢谢,