zoukankan      html  css  js  c++  java
  • 表单本地安全提交

    【安全提交表单数据的方法】
    为 了保证安全性,在解答中,将用户所提交的字符串值首先进行编码,这样字符串中所有的“<”和“>”标记将失效,为了能使部分HTML标记生 效,可以利用替换的方法,将部分HTML标记恢复。这种方法使用非常简单,在保证了安全性的同时,允许用户输入部分HTML标记。
     
     
     

     
    【HTML表单的提交方式】
    HTML表单的提交方式: 两个重要的属性 action  和 method
    (1) action 属性指明当前表单提交后由哪个程序来处理,这个处理程序可以是任何动态网页
    (2) method 属性指明form表单的提交方式,它有两个可能的值: get 和  post
    1.  get 和  post 有以下的区别:
    一:  以get 方式提交的表单地址栏中会显示参数名和参数值;而post方式不会,用post提交参数相对更隐秘些,也相对更安全些。
    二: 由于浏览器地址栏中能输入的最大字节数有限,所以用get方式提交不能处理参数值更大的表单,而post方式则没有这个限制。
     

    【html表单提交的几种方法】 原文地址: http://www.ijser.cn/?p=34

    最普通最常用最一般的方法就是用submit type..看代码:  
    <form name=”form” method=”post” action=”#">  
    <input type=”submit” name=”submit” value=”提交">  
    </form> 

    另外,还有一种常用的方法是使用图片:  
    <form name=”form” method=”post” action=”# ">  
    <input type=”image” name=”submit” src=”btnSubmit.jpg”>  
    </form> 

    第三种是使用链接来提交表单,用到了javascript的DOM模型:  
    <form name=”form” method=”post” action=”#”>  
    <a href=”javascript:form.submit();”>提交</a>  
    </form>  
    这种方法实际上是调用了一个javascript函数,使用javacript函数来提交表单,方法就非常多非常灵活了,比如可以把它加入到任意一个标签的onclick事件中:  
    <form name=”form” method=”post” action=”#”>  
    <div onclick=”javascript:form.submit();”>  
    <span>提交</span>  
    </div>  
    </form> 

    但是,如果一个表单里有需要有多个提交按钮怎么办呢?  
    比如一个表单里的提交按钮所指向的处理页面不同,这样由于表单在定义的时候就已经确定下表单数据的处理页面,所以单纯地在表单里放多个提交按钮是没有办法达到目的的。这就需要javascript。  
    首先定义一个函数:  
    <script language=javascript>  
    function query(){  
    form.action=”query.php”;  
    form.submit();}  

    function update(){  
    form.action=”update.php”;  
    form.submit();}  
    </script>  
    通过javascript改变form的action属性值,这样就可以实现多提交按钮而且功能不同了,页面内代码如下:  
    <form name=”form” method=”post” action=”#”>  
    <input type=”button” name=”query” onclick=”query();” value=”查询”>  
    <input type=”button” name=”update” onclick=”update();” value=”更新”>  
    </form>  
    上面一段代码,使用的是普通的按钮,而提交功能的实现方法是在它的onclick事件中调用javascript函数.  

    有了上面这几种提交表单的方法,我想差不多够应付复杂的表单了。

    【如何防止FORM表单本地提交?】【防止form表单重复提交】
    把当前页面表单页面 HTML代码下载到本地,然后存为HTML。要知道提交的ACTION地址 就可以在本地提交。
     
    添加验证字段,判断是否同一授权人提交的。对表单资格的许可。
     

    【如何防止Form页面重复提交】
    服务器端验证 提交页面的来源 Request.Headers.Get("referer");,如果不是本站过来的就不允许提交。
     
    加一个令牌,通过判断令牌的值来判断是不是属于重复提交。
     
    设置页面过期,后退后,页面失效。
     
    form建立的时候,生成一个session。
    session.formuuid = "一个随机数"
    <form>
       <input type="hidden" value="<%=session.formuuid%>">
    </form>
    提交后,判断request("formuuid")和session.formuuid是否一致。
    if request("formuuid") = session.formuuid then
     '处理过程
      session.formuuid = "另外一个新的随机数"
    end if
     
    利用Session防止表单提交
     1、产生页面时,服务器为每次产生的Form分配唯一的随机标识号,并且在form的一个hidden隐藏字段中设置这个标识号,同时在当前用户的Session中保存这个标识号。
     2、当提交表单时,服务器比较hidden和session中的标识号是否相同,相同则继续,处理完后清空Session,否则服务器忽略请求。
     
    恶意用户可利用这一性质,不断重复访问页面,以致Session中保存的标识号不断增多,最终严重消耗服务器内存。  因此一些网站通常采用在Session中记录用户发帖的时间,然后通过一个时间间隔来限制用户连续发帖的数量。

    【表单提交过一次以后如何防止刷新页面重新提交表单】【  http://bbs.csdn.net/topics/390746779?page=1 】
    ——客户端异步处理,然后再回写个东西给隐藏域。提交的时候先判断隐藏域,是否已经可以提交。
    ——重定向其他页面。

    【防止页面多次刷新提交表单(转)】【http://ywj-sh110-163-com.iteye.com/blog/732419
    当用户从表单处完成递交,如无问题已将注册信息写入数据库,但有问题的是,如何防止用户刷新页面,这相当于将原有的信息再次写入数据库,在网络上寻找解决方法,试用后将本人认为最管用的方法记下。
     
    网络中给出如下解决方式:
    第一种:禁用提交按钮
    当用户提交表单后,使用JAVASCRIPT脚本语言,将提交钮禁用。
    分析:如客户端没有开启脚本功能就出现问题;这也仅是在表单处理前有用,防止用户多次点击提交钮;现在很多网站都  启用验证码解决此问题了。
     
    第二种:使用 Session
    在第一次写入数据库代码后,  将Session标记;在数据库代码前判断Session是否曾经标记过并与刚才的标记是否相等。
    代码:
    Session("User") = True
       Response.write "您刚才已经注册过了……"
    Else
       ...... '省略写入数据库部分
       Session("User") = True
    End if
    分析:比较管用的;但Session默认时效为20分钟,虽然可以设置时效长度,但由于网站服务器设置不同,也许达不到理想效果。
     
    第三种:重新定向
    注册完毕后直接将网页重新定向到其他页面。
    代码:Response.Redirect "Index.html"
    分析:使用此方法,需要  配合客户端脚本清除历史(history)才行,没有试用,因为用户可以使用后退按钮,继续刷新。
     
    第四种:  禁止缓存
    在写入数据一页最下边添加下面的代码,然后导向新页,可以  使用户点击后退按钮后,页面提示网页过期
    代码:
    ASP:
    Response.Buffer = True    
    Response.ExpiresAbsolute = Now() - 1    
    Response.Expires = 0    
    Response.CacheControl = "no-cache"
    ASP.NET:
    Response.Buffer=true;
    Response.ExpiresAbsolute=DateTime.Now.AddSeconds(-1);
    Response.Expires=0;
    Response.CacheControl="no-cache";
    分析:试用后,发现一个问题,虽然表面看到网页过期字样,但在过期网页上刷新,仍可以再次刷新多次注册。
     
    第五种:用弹出窗口
    提交表单的时候弹出新窗口(在新窗口页面完成数据库的写入),关闭本窗口。对于window.open()打开的窗口是无法用后退按钮的。
     
    第六种:调数据库进行对比
    这一种是得不偿失的方法,因为会加重服务器的负担,如果在表单没有进行AJAX方式的验证,这也算是一种必要的方法。
    代码:(假设已连接数据库)
    Dim Rs,SQL,UserId
    UserId = Request("Userid") '从表单从取数据内容
    If UserId <> "" then '不为空的时候
    Set Rs=Server.CreateObject("Adodb.Recordset")
       SQL = "Select Userid From 表 Where Userid='"& UserId &"'"
       Rs.Open Sql, Conn, 2, 2
     
    If Rs.Eof And Rs.Bof Then
       Response.Write "没有相同数据!"
    Else
       Response.Write "有相同数据!"
    End If
     
       Rs.Close
       Set Rs = Nothing
       Response.End
    End If
     
    经过测试,如果不想太费事,直接用第六种方法,用户刷一次就对数据库检索一次,这种方式最大的弊端就是有可能把服务器累死;
     
    由于,我采用了第二种方法,结合了第四种(效果不大),在代码最前端加入了  验证由何处来本站的函数,这样可以防止用户自己在本机模仿网站表单提交数据(hi.baidu.com/76512/blog/item/b8d9be8f168d3aedf01f3680.html),也可以防止用户在本站直接在网址末端加变量值刷新数据。
     
    由于在表单处已加入随机验证码,并已写入Session中,在处理数据前,可以先检测Session是否为空,空为已提交过了,不为空是第一次提交,在  第一次提交后将该Session清空
     
    代码:
    If Session("RndNum") = ""
       Response.Write "已提交过数据了呀!"
    Else
    ...... '省略写入数据库代码
       Session("RndNum") = ""
    End if
    分析:  只要是从正常的途径递交的表单,Session("RndNum")的数值不会为空的。
     
    从非正常途径,  Session为空!(比如说,直接打开网址,或在本机模拟表单递交,或在网址后添加变量值,是无法写入数据库的。Session默认的20分钟,清空后仍然符合逻辑。也不怕用户打开几个注册页面,来回刷新注册。

    【禁用页面缓存的几种方法(静态和动态)】
    1、在Asp页面首部<head>加入  
    以下是引用片段:
      Response.Buffer   =   True    
      Response.ExpiresAbsolute   =   Now()   -   1    
      Response.Expires   =   0    
      Response.CacheControl   =   "no-cache"    
      Response.AddHeader   "Pragma",   "No-Cache"  
     
    2、在HtML代码中加入  
    以下是引用片段:
      <HEAD>    
      <META   HTTP-EQUIV="Pragma"   CONTENT="no-cache">    
      <META   HTTP-EQUIV="Cache-Control"   CONTENT="no-cache">    
      <META   HTTP-EQUIV="Expires"   CONTENT="0">    
      </HEAD>  
     
       
    3、在重新调用原页面的时候在给页面传一个参数   Href="****.asp?random()"
    前两个方法据说有时会失效,而第三种则是在跳转时传一个随机的参数! 因为aspx的缓存是与参数相关的,如果参数不同就不会使用缓存,而会重新生成页面,每次都传一个随机的参数就可以避免使用缓存。这个仅适用于asp&asp.net
    4、在jsp页面中可使用如下代码实现无缓存:
    以下是引用片段:
    response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
    response.setHeader("Pragma","no-cache"); //HTTP 1.0
    response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
    这些代码加在<head> </head>中间具体如下
    以下是引用片段:
    <head>
    <%
    response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
    response.setHeader("Pragma","no-cache"); //HTTP 1.0
    response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
    %>
    </head>
    5、window.location.replace("WebForm1.aspx");  
    参数就是你要覆盖的页面,replace的原理就是用当前页面替换掉replace参数指定的页面。  
    这样可以防止用户点击back键。使用的是javascript脚本,举例如下:
    a.html
    以下是引用片段:
    <html>
        <head>
            <title>a</title>      
            <script language="javascript">
                function jump(){
                    window.location.replace("b.html");
                }
            </script>
        </head>
        <body>
           <a href="javascript:jump()">b</a>
       </body>
    </html>  
    b.html
    以下是引用片段:
    <html>
        <head>
            <title>b</title>      
            <script language="javascript">
                function jump(){
                    window.location.replace("a.html");
                }
            </script>
        </head>
        <body>
           <a href="javascript:jump()">a</a>
       </body>
    </html>  
    前 4种只是清空了cache,即存储在Temporary Internet Files文件夹中的临时文件,而第五种则是使用跳转页面文件替换当前页面文件,并没有清空cache,也就是说Temporary Internet Files产生了相关的临时文件,两者搭配使用真是清空缓存,必备良药。
     

    【防止非本站地址注册表单】
     
    今天写程序,考虑到如果有个别用户在本机模拟表单注册网站ID,或发表贴子,怎么办?
    编写如下代码,在注册页面和注册完毕的页面调用:
    Function CheckPost()
    Dim Server_v1,Server_v2
    CheckPost = False
    Server_v1 = Cstr(Request.ServerVariables("HTTP_REFERER"))
    Server_v2 = Cstr(Request.ServerVariables("SERVER_NAME"))
     
    If Mid(Server_v1,8,Len(Server_v2))<>Server_v2 then
       CheckPost=False
    Else
       CheckPost=True
    End If
    End Function
    然后在页面中调用:
    If Not CheckPost() Then
       Response.Write "请从正确地址注册"
    End if
     

    【[Jsp]防止页面表单重复提交的解决方法】【  http://www.cnblogs.com/SCAU_que/articles/2009458.html】 【源代码】  
    当我们写了个注册页面时候,用户完成注册并提交,用户注册的资料并录入数据库保存,最不希望出现的是在一个会话中出现多次提交的结果,我们可以通过为请求设置标记来避免此类事件的发生。   
    1.为每个请求设置一个标记,当此页面是首次被请求时,生成  标记并放入session中,并且把此生成的标记的值 作为隐含标签传递到处理页面。   
    2.提交表单时,跳转页面处理请求中的标记,如果  判断请求中session对象的标记和隐含标签中的值相同,处理请求,  并将session中的标记值去除

    ( TokenGen.java)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    package com.beans;
     
    import java.util.*;
    import javax.servlet.http.*;
     
    public class TokenGen {
        private static TokenGen instance = new TokenGen();
     
        private TokenGen() {}
     
        public static TokenGen getInstance() {
            return instance;
        }
     
        public synchronized boolean isTokenValid(HttpServletRequest request) {
            // 没有session,判为非法
            HttpSession session = request.getSession(false);
            if (session == null)
                return false;
     
            // session中不含token,
            // 说明form被提交过后执行了resetToken()清除了token
            // 判为非法
            String stoken = (String) session.getAttribute("token");
            if (stoken == null)
                return false;
     
            // request请求参数中不含token,
            // 判为非法
            String rtoken = request.getParameter("token");
            if (rtoken == null)
                return false;
     
            // request请求中的token与session中保存的token不等,判为非法
            return stoken.equals(rtoken);
        }
         
        /*
         * 重新设置token,当页面被请求后,将session中的token属性去除
         */
        public synchronized void resetToken(HttpServletRequest request)
        {
            HttpSession session = request.getSession(false);
            if (session!=null)
            {
                session.removeAttribute("token");
            }
        }
        /*
         * 为请求新建一个token标记,此标记由一个随机的double数toString形成,并把字符值存入session中
         */
         
        public synchronized void saveToken(HttpServletRequest request)
        {
            HttpSession session = request.getSession(true);
            Random rand = new Random();
            Double d = rand.nextDouble();
            session.setAttribute("token", d.toString());   
        }
    }
    1
     
    (form.jsp) 其中加粗加红为生成token标记的代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    <%@ page language="java" import="com.beans.*" pageEncoding="gb2312"%>
     
     
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
     <head>
     
      <title>注册页面1</title>
     
      <meta http-equiv="pragma" content="no-cache">
      <meta http-equiv="cache-control" content="no-cache">
      <meta http-equiv="expires" content="0">
      <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
      <meta http-equiv="description" content="This is my page">
     </head>
     <%
      TokenGen.getInstance().saveToken(request);
      String s = (String)session.getAttribute("token");
     %>
     <body>
      <form id="form1" name="form1" method="post" action="register.jsp">
       
       <table align="center">
       <tr>
        <td colspan="2"><br><input type="hidden" name="token" value="<%=s%>"/>
        </td>
       </tr>
        <tr>
         <td align="right">
          用户名:
         </td>
         <td>
          <input type="text" name="t1" />
         </td>
        </tr>
     
        <tr>
         <td align="right">
          密码:
         </td>
         <td>
          <input type="password" name="t2" />
         </td>
        </tr>
     
        <tr>
         <td align="right">
          确认密码:
         </td>
         <td>
          <input type="password" name="t3" />
         </td>
        </tr>
     
        <tr>
         <td align="right">
          性别:
         </td>
         <td>
          <input type="radio" name="radio" id="radio" value="boy" />
          
          <input type="radio" name="radio" id="radio2" value="gril" />
          
         </td>
        </tr>
     
        <tr>
         <td align="right">
          个人说明:
         </td>
         <td>
          <textarea name="textraea1" rows="15" cols="60"></textarea>
         </td>
        </tr>
     
        <tr>
         <td align="right">
          <input type="submit" name="button" id="button" value="提交" />
         </td>
         <td>
          <input type="reset" name="button2" id="button2" value="重置" />
         </td>
        </tr>
       </table>
      </form>
     </body>
    </html>
    (register.jsp)处理请求
       
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <%@ page language="java" import="com.beans.*" pageEncoding="gb2312"%>
     
     
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
     
         
        <title>处理注册页面1</title>
         
     <meta http-equiv="pragma" content="no-cache">
     <meta http-equiv="cache-control" content="no-cache">
     <meta http-equiv="expires" content="0">   
     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
     <meta http-equiv="description" content="This is my page">
     <!--
     <link rel="stylesheet" type="text/css" href="styles.css">
     -->
     
      </head>
       
      <body>
       <%
        TokenGen tokenGen=TokenGen.getInstance();
        if (!tokenGen.isTokenValid(request))
        {
         out.print("这是重复提交或非法提交!");
        }
        else
        {
         // 处理请求,并执行resetToken方法,将session中的token去除
         tokenGen.resetToken(request);
        }
         
        %>
      </body>
    </html>
    其中还有一种是通过设置时间间隔来限制重复提交,其实现原理和上面的大同小异。
  • 相关阅读:
    Maven pom.xml文件获取当前时间戳
    maven依赖jdk的tools.jar包坐标怎么依赖
    解决Git问题:git登录账号密码错误remote: Incorrect username or password、如何快速关联/修改Git远程仓库地址、git修改用户名邮箱密码
    浅析Java里的内存分析及常量池加强对Java里字符串的理解
    浅析Java数据结构:稀疏数组的介绍和使用场景
    UmiJS简单介绍及使用UmiJS开发结构浅析
    React基础知识笔记:如何渲染html代码、条件渲染与循环渲染、如何获取动态路由传参、动态设置背景图、umi+dva中全局使用dispatch
    git commit提交时报错husky > pre-commit (node v10.16.3)
    浅析npm报错ENOTFOUND npm ERR! network request to https://npm.***.com/*** failed 及 .npmrc 文件的作用、npm --verbose命令
    浅析为什么说Java中只有值传递
  • 原文地址:https://www.cnblogs.com/lsx1993/p/4632104.html
Copyright © 2011-2022 走看看