在Web开发中,必须面对的问题就是表单的重复提交问题(这里仅指F5刷新造成的重复提交),.NET中处理这个问题似乎没有什么好的方法。 在网上搜索得到的解决方法主要有两种,一种是直接让表单按钮失效,从而保证一个用户对于一个表单只能提交一次;另一种方法,是一次提交后把表单清空,在后台逻辑上进行判断,从而区分是否重复提交。 
个人感觉,第一种方法,用户体验不好,按钮只能按一次,这种应该是用来防治多次点击提交按钮造成的重复提交的,无法防止刷新造成的二次提交;第二种,两种重复提交都可以防止,但是表单内容就没了,万一有需求不让内容消失,就费些周折。 
于是,自己模仿JSP中Struts的令牌,写了一个防止表单被重复提交的方法,和大家分享。 
实现原理: 
由于刷新提交表单,实际上提交的就是上一次正常提交的表单,所以我们只要做一个标志,判断出是新表单还是上一次的旧表单就可以分辨出是否进行了重复提交操作。 
实现方法: 
在页面上放置一个Hidden域,当页面第一次载入的时候,在Session里面保存一个标志,同时,把这个标志保存到页面上的Hidden里面。在提交表单时,判断表单中提交上来的Hidden和Session中的标志是否一致,就可以知道是正常的提交表单,还是刷新页面导致的重复提交。需要注意的是,在每次提交表单的处理之后,要更新Session里面的标志。 
代码实例: 
代码很少,首先是页面上。

  1. <html xmlns="http://www.w3.org/1999/xhtml" >
  2. <head runat="server">
  3. <title></title>
  4. </head>
  5. <body>
  6. <form id="form1" runat="server">
  7. <div>
  8. <input type="text" id="tbxName" runat="server"/>
  9. <input type="text" id="tbxPass" value="" runat="server"/>
  10. <asp:Button ID="btnSubmit" runat="server" OnClick="Button1_Click" Text="Button" />
  11. <asp:Label ID="lblMessage" runat="server" Text=""></asp:Label>
  12. <input id="hiddenTest" type="hidden" value="<%= GetToken() %>" name="hiddenTestN"/>
  13. </div>
  14. </form>
  15. </body>
  16. </html>

需要注意的地方: 
    1 GetSessionToken()函数是为了获得 Session里面保存的标志。 
    2 Hidden使用了非服务器控件,这是因为我使用服务器控件,并在后台直接获取Session的标志并赋值给这个Hidden的时候,刷新提交到服务器的 表单中的Hidden的值也发生了改变,猜想是服务器控件的话,表单里面的值是保持同步的,当然,也可能是我用的方法不对,嘎嘎。 
下面是后台代码:

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Web;
  5. using System.Web.Security;
  6. using System.Web.UI;
  7. using System.Web.UI.WebControls;
  8. using System.Web.UI.WebControls.WebParts;
  9. using System.Web.UI.HtmlControls;
  10. using System.Security.Cryptography;
  11. using System.Text;
  12. public partial class _Default : System.Web.UI.Page
  13. {
  14. protected void Page_Load(object sender, EventArgs e)
  15. {
  16. //第一次载入的时候,生成一个初始的标志
  17. if (null == Session["Token"])
  18. {
  19. SetToken();
  20. }
  21. }
  22. protected void Button1_Click(object sender, EventArgs e)
  23. {
  24. if (Request.Form.Get("hiddenTestN").Equals(GetToken()))
  25. {
  26. lblMessage.ForeColor = System.Drawing.Color.Blue;
  27. lblMessage.Text = "正常提交表单";
  28. SetToken();//别忘了最后要更新Session中的标志
  29. }
  30. else
  31. {
  32. lblMessage.ForeColor = System.Drawing.Color.Red;
  33. lblMessage.Text = "刷新提交表单";
  34. }
  35. }
  36. //获得当前Session里保存的标志
  37. public string GetToken()
  38. {
  39. if (null != Session["Token"])
  40. {
  41. return Session["Token"].ToString();
  42. }
  43. else
  44. {
  45. return string.Empty;
  46. }
  47. }
  48. //生成标志,并保存到Session
  49. private void SetToken()
  50. {
  51. Session.Add("Token", UserMd5(Session.SessionID + DateTime.Now.Ticks.ToString()));
  52. }
  53. //这个函数纯粹是为了让标志稍微短点儿,一堆乱码还特有神秘感,另外,这个UserMd5函数是网上找来的现成儿的
  54. protected string UserMd5(string str1)
  55. {
  56. string cl1 = str1;
  57. string pwd = "";
  58. MD5 md5 = MD5.Create();
  59. // 加密后是一个字节类型的数组
  60. byte[] s = md5.ComputeHash(Encoding.Unicode.GetBytes(cl1));
  61. // 通过使用循环,将字节类型的数组转换为字符串,此字符串 是常规字符格式化所得
  62. for (int i = 0; i < s.Length; i++)
  63. {
  64. // 将得到的字符串使用十六进制类型格式。格式后的字符是 小写的字母,如果使用大写(X)则格式后的字符是大写字符
  65. pwd = pwd + s[i].ToString("X");
  66. }
  67. return pwd;
  68. }
  69. }

需要注意的地方: 
    1 在页面第一次载入的时候要生成标志,以后就不用了。 
    2 在表单处理的函数的最后,记得要更新标志。 
    3 标志我选用了当前SessionID加上当前时间毫秒值,这样基本可以避免标志重复,之后进行了一次MD5,纯粹为了让标志短点儿,当然有一点点安全的意 思,哈哈。 
所有代码就是这些,很简单,不知道是因为太简单还是大家有更好的方法,我在网上没有找到类似的代码,所以写下来和大家分享,如果有更好的方法,希望可以告诉我,因为好久不做Web开发了,怕是有很多新技术都不会了。

刷新本页: 
Response.Write( " <script   language=javascript> window.location.href=window.location.href; </script> ")

刷新父页: 
Response.Write( " <script   language=javascript> opener.location.href=opener.location.href; </script> ")

转到指定页: 
Response.Write( " <script   language=javascript> window.location.href= 'yourpage.aspx '; </script> ")

页面按F5重复提交数据解决方法的更多相关文章

  1. PHP防止页面刷新、重复提交数据

    PHP防止页面刷新.重复提交数据 (2011-12-09 16:52:45) 转载▼ 标签: it 分类: php技术相关 闲来无事看了一下php session ,又在网上看了防止页面刷新重复提交数 ...

  2. PHP防止表单重复提交的解决方法

    PHP+SESSION防止表单重复提交 index.php 当前表单页面is_submit设为0 SESSION_START(); $_SESSION['is_submit'] = 0; <fo ...

  3. [Jsp]防止页面表单重复提交的解决方法

    个人学习笔记,写下方便以后复用. 当我们写了个注册页面时候,用户完成注册并提交,用户注册的资料并录入数据库保存,最不希望出现的是在一个会话中出现多次提交的结果,我们可以通过为请求设置标记来避免此类事件 ...

  4. java表单重复提交常用解决办法

    最近在看些基础的东西,顺便做下笔记.相信大家在平时网页使用中,经常会有按钮重复点击,然后点不动刷新,还有当网络延时比较厉害点了没反应在点击的重复提交.为了避免这种情况,总结了一下4点处理方案 表单重复 ...

  5. 用sql删除数据库重复的数据的方法

      /***********************************************两个意义上的重复记录:1.是完全重复的记录,也即所有字段均重复的记录,2.是部分关键字段重复的记录, ...

  6. ASP模拟POST请求异步提交数据的方法

    这篇文章主要介绍了ASP模拟POST请求异步提交数据的方法,本文使用MSXML2.SERVERXMLHTTP.3.0实现POST请求,需要的朋友可以参考下 有时需要获取远程网站的某些信息,而服务器又限 ...

  7. JavaScript刷新页面,不重复提交

    location.replace(location.href);//刷新页面,不重复提交

  8. svn新建文件不能提交的解决方法

    svn新建文件不能提交的解决方法 在当前新建文件的目录下,右键空白处: 选择Properties 找到所有有ignore字眼的属性,查看这个属性的继承目录(inherited from),入我的是cl ...

  9. Eclipse 新建.jsp页面后,页面头部标签报错的解决方法

    Eclipse 新建.jsp页面后,页面头部标签报错的解决方法 1.报错地方: 2.解决方法: .jsp页面右键==>BUild Path ==>Configure Build Path. ...

随机推荐

  1. libev事件库学习笔记

    一.libev库的安装 因为个人的学习环境是在ubuntu 12.04上进行的,所以本节仅介绍该OS下的安装步骤. 使用系统工具自动化安装: sudo apt-get install libev-de ...

  2. 精讲N皇后问题

             思想:存三个数组记录记录走的过程,运用回溯不符合或row==n+1就跳出当前层,直到找完:递归时的路径都在保存着,当连续跳出到第一次进入的dfs且i=n时就全部跳出dfs函数了: # ...

  3. HTML5 HybridApp开发上手指引

    眼下我们项目是基于AngularJS和ionic框架开发的Hybrid App.支持android phone/pad, iPhone,iPad四个平台版本号.以及微信版. 由于使用的技术有点新,所以 ...

  4. 多线程中的lua同步问题

    最近写paintsnow::start时出现了一个非常麻烦的BUG,程序的Release版本大约每运行十几次就会有一次启动时崩溃(Debug版本还没崩溃过),崩溃点也不固定.经过简单分析之后,确定是线 ...

  5. 【Java基础】setter与getter方法

    //下面代码实现设置和获取学生姓名和成绩. class lesson5homework { public static void main(String[] args) { TestCode TC=n ...

  6. WeixinJSBridge:微信浏览器内置JavaScript 对象

    微信公众平台开始支持前端网页,大家可能看到很多网页上都有分享到朋友圈,关注微信等按钮,点击它们都会弹出一个窗口让你分享和关注,这个是怎么实现的呢?今天就给大家讲解下如何在微信公众平台前端网页上添加分享 ...

  7. SqlServer判断数据库、表、存储过程、函数是否存在

    假设场景是: 需要给一个脚本给客户更新, 这个对象可能存在或不存在 -- 更新存储过程 USE [数据库名] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ...

  8. javascript XMLHttpRequest对象全面剖析

    转载:http://www.jb51.net/article/23175.htm 一. 引言 异步JavaScript与XML(AJAX)是一个专用术语,用于实现在客户端脚本与服务器之间的数据交互过程 ...

  9. 关于OC中的几种代码延迟执行方式

    第一种: [UIView animateWithDuration:3 delay:3 options:1 animations:^{         self.btn.transform = CGAf ...

  10. Marineking wilyin

    A - Marineking wilyin Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Ot ...