• PHP+jQuery 注册模块开发


    /*
    ******* 环境: Apache2.2.8 + PHP5.2.6 + MySQL5.0.51b + jQuery-1.8.3.min.js *******
    ******* 其他组件:Zend_mail( Zend_framework 1.11.11 )
    ******* Date:2014-09-25
    ******* Author:小dee
    ******* Blog:http://www.cnblogs.com/dee0912/
    */

    写了一个简单的PHP+jQuery注册模块,需要填写的栏目包括用户名、邮箱、密码、重复密码和验证码,其中每个栏目需要具备的功能和要求如下图:

    在做这个模块的时候,很大程度上借鉴了网易注册( http://reg.163.com/reg/reg.jsp?product=urs )的功能和样式。但网易对于每个栏目的判断的做法是:在输入文字时,并不给出任何实时的检测结果,而在这个栏目失去焦点时,才把检测的结果展示出来,这种做法我认为会使用户在输入时视觉上比较统一,看到的是关于该栏目要求的提示,不会出现其他信息的打扰,但同时也不会得到正在输入的字符的检测提示。所以在做这个功能的时候,我把我自认为需要实时提示的一些信息做了相应的加强,比如用户名长度超过限制和密码的长度以及强弱,并且给邮箱的大写锁定做了简单的判断。

    注:表单的提交按钮type为button而不是submit,因此所有栏目的回车( keydown )都统一设置为将焦点移至下一个栏目,除了最后一个栏目验证码,在验证码栏目使用回车( keydown )会触发提交事件。

    功能分析

    用户名栏目:

    流程

    ①页面加载完即获得焦点,获得焦点时出现初始说明文字;

    ②鼠标点击用户名输入框,出现初始说明文字;

    ③输入字符,即时提示是否符合长度要求;

    ④失去焦点时首先判断是否为空,为空时提示不能为空;非空且长度满足要求时,开始检测用户名是否被注册;

    ⑤用户名已被注册,给出提示,如果没有注册,则提示可以注册;

    ⑥再次获得焦点时,不论输入框中是否有输入,或是否输入符合规定,都出现初始说明文字

    ⑦回车时将焦点移至邮箱栏目

    如图:

    细节

    可以使用任意字符,并且字数限制为:中文长度不超过7个汉字,英文、数字或符号长度不超过14个字母、数字或符号(类似豆瓣注册https://www.douban.com/accounts/register),即不超过14个字符

    关于占位符(字符长度),一个汉字的占位符是2,一个英文(数字)的占位符是1,可以用php语句来计算字符的长度

    1 <?php
    2 //php.ini开启了php_mbstring.dll扩展
    3 $str="博客园小dee";
    4  
    5 echo (strlen($str)+mb_strlen($str,'utf-8'))/2;

    输出:11

    而strlen($str) 输出的是15:4*3+3,汉字在utf-8编码下占3个字节,英文占1个,

    mb_strlen($str,'utf-8') 输出的是7:一个汉字的长度是1,

    如果用jquery的length来输出这个字符串,alert($("#uname").val().length),则会得到长度7,

    这点要注意。

    同时用户名两端不能含有空格,在检测以及注册时,程序会自动过滤用户名两端的空格。

    register.html 用户名栏目的HTML代码片段:

    1 <!-- 用户名 -->        
    2 <div class="ipt fipt">
    3     <input type="text" name="uname" id="uname" value="" placeholder="输入用户名"  autocomplete="off" />
    4     <!--提示文字-->
    5     <span id="unamechk"></span>
    6 </div>

    register.js公用部分的js代码:

     1 $(function(){
     2     
     3     //说明文字
     4     function notice(showMsg,noticeMsg){            
     5         showMsg.html(noticeMsg).attr("class","notice");
     6     }
     7     //显示错误信息
     8     function error(showMsg,errorMsg){    
     9         showMsg.html(errorMsg).attr("class","error");
    10     }    
    11     //显示正确信息
    12     function success(showMsg,successMsg){    
    13         showMsg.html(successMsg)                
    14                        .css("height","20px")
    15                        .attr("class","success");
    16     }
    17 
    18     //计算字符长度
    19     function countLen(value){
    20     
    21         var len = 0; 
    22         for (var i = 0; i < value.length; i++) { 
    23             if (value[i].match(/[^x00-xff]/ig) != null) 
    24             len += 2; 
    25             else 
    26             len += 1; 
    27         } 
    28         return len;
    29     }                     
    30 
    31     //......
    32 )};

     register.js用户名部分的js代码:

     1 //检测用户名长度
     2 function unameLen(value){
     3     
     4         var showMsg = $("#unamechk");
     5 
     6         /* (strlen($str)+mb_strlen($str))/2 可得出限制字符长度的上限,
     7         *  例如:$str为7个汉字:"博客园记录生活",利用上面的语句可得出14,
     8         *  同样,14个英文,利用上面的语句同样能得出字符长度为14
     9         */
    10         if(countLen(value) > 14){
    11                         
    12             var errorMsg = '用户名长度不能超过14个英文或7个汉字';
    13             error(showMsg,errorMsg);        
    14         }else if(countLen(value) == 0){
    15         
    16             var noticeMsg = '用户名不能为空';
    17             notice(showMsg,noticeMsg);
    18         }else{
    19 
    20             var successMsg = '长度符合要求';
    21             success(showMsg,successMsg);
    22         }
    23 
    24         return countLen(value);
    25     }
    26 
    27     //用户名
    28     unameLen($("#uname").val());
    29     
    30     $("#uname").focus(function(){
    31     
    32                     var noticeMsg = '中英文均可,最长为14个英文或7个汉字';
    33                     notice($("#unamechk"),noticeMsg);
    34                 })
    35                .click(function(){
    36                     
    37                     var noticeMsg = '中英文均可,最长为14个英文或7个汉字';
    38                     notice($("#unamechk"),noticeMsg);
    39                 })
    40                .keyup(function(){
    41     
    42                     unameLen(this.value);
    43                 }).keydown(function(){
    44                 
    45                     //把焦点移至邮箱栏目
    46                     if(event.keyCode == 13){
    47                         
    48                         $("#uemail").focus();
    49                     }
    50                 })
    51                 .blur(function(){
    52                 
    53                     if($("#uname").val()!="" && unameLen(this.value)<=14 && unameLen(this.value)>0){
    54                         //检测中
    55                         $("#unamechk").html("检测中...").attr("class","loading");
    56                         //ajax查询用户名是否被注册
    57                         $.post("./../chkname.php",{
    58                         
    59                             //要传递的数据
    60                             uname : $("#uname").val()
    61                         },function(data,textStatus){
    62                             
    63                             if(data == 0){
    64                             
    65                                 var successMsg = '恭喜,该用户名可以注册';
    66                                 $("#unamechk").html(successMsg).attr("class","success");
    67 
    68                                 //设置参数
    69                                 nameval = true;
    70                             }else if(data == 1){
    71                             
    72                                 var errorMsg = '该用户名已被注册';
    73                                 error($("#unamechk"),errorMsg);
    74                             }else{
    75                             
    76                                 var errorMsg = '查询出错,请联系网站管理员';
    77                                 error($("#unamechk"),errorMsg);
    78                             }
    79                         });
    80                     }else if(unameLen(this.value)>14){
    81                     
    82                         var errorMsg = '用户名长度不能超过14个英文或7个汉字';
    83                         error($("#unamechk"),errorMsg);
    84                     }else{
    85                     
    86                         var errorMsg = '用户名不能为空';
    87                         error($("#unamechk"),errorMsg);
    88                     }
    89 });
    90 
    91 //加载后即获得焦点
    92 $("#uname").focus();

    checkname.php代码:

     1 <?php
     2 
     3     header("charset=utf-8");
     4 
     5     require_once("conn/conn.php");
     6 
     7     if(isset($_POST['uname']) && $_POST['uname']!=""){
     8     
     9         $uname = trim(addslashes($_POST['uname']));
    10     }
    11 
    12     $sql = "select uname from user where uname='".$uname."'";
    13     
    14     if($conne->getRowsNum($sql) == 1){
    15     
    16         $state = 1;
    17     }else if($conne->getRowsNum($sql) == 0){
    18     
    19         $state = 0;
    20     }else{
    21 
    22         echo $conne->msg_error();
    23     }
    24 
    25     echo $state;

    提示文字( Chrome下 )

    ①初始获得焦点、再次获得焦点或点击时

     

           

    ②输入时实时检测长度

           

       

    ③删除至空且未失去焦点时,使用蓝色图标提示不能为空——用户在输入时看起来不突兀

           

    ④失去焦点且不为空,检测是否被注册( 非常短暂,一闪而过 )

         

    ⑤失去焦点时为空、可以注册、已被注册时

           

           

           

    用户名分析至此完毕。

    邮箱栏目:

    流程

    ①当栏目获得焦点或者点击时不论栏目为空、填写正确或者填写错误时都出现说明文字;

    ②用户输入时出现下拉菜单显示多种邮件后缀供用户选择;

    失去焦点时首先判断邮箱格式是否正确,如果正确则检测邮箱是否被注册 ;

    ④在使用回车选择下拉菜单时,将自动填充邮箱栏目;没有出现下拉菜单时,将焦点移至密码栏目

    如图:

    register.html 邮箱栏目HTML代码片段:

    1 <!-- email -->            
    2 <div class="ipt">
    3     <input type="text" name="uemail" id="uemail" value="" placeholder="常用邮箱地址" />
    4     <span id="uemailchk"></span>
    5     <ul class="autoul"></ul>
    6 </div>    

    下拉功能emailup.js同之前的博文《jQuery实现下拉提示且自动填充的邮箱》,略有修改,注意用回车( keydown和keyup事件 )在不同情况下触发的不同动作:

      1 $(function(){
      2     
      3     //初始化邮箱列表
      4     var mail = new Array("sina.com","126.com","163.com","gmail.com","qq.com","hotmail.com","sohu.com","139.com","189.cn","sina.cn");
      5 
      6     //把邮箱列表加入下拉
      7     for(var i=0;i<mail.length;i++){
      8     
      9         var $liElement = $("<li class="autoli"><span class="ex"></span><span class="at">@</span><span class="step">"+mail[i]+"</span></li>");
     10 
     11         $liElement.appendTo("ul.autoul");
     12     }
     13 
     14     //下拉菜单初始隐藏
     15     $(".autoul").hide();
     16     
     17     //在邮箱输入框输入字符
     18     $("#uemail").keyup(function(){
     19      
     20         if(event.keyCode!=38 && event.keyCode!=40 && event.keyCode!=13){
     21 
     22             //菜单展现,需要排除空格开头和"@"开头
     23             if( $.trim($(this).val())!="" && $.trim(this.value).match(/^@/)==null ) {
     24 
     25                 $(".autoul").show();
     26                 //修改
     27                 $(".autoul li").show();
     28 
     29                 //同时去掉原先的高亮,把第一条提示高亮
     30                 if($(".autoul li.lihover").hasClass("lihover")) {
     31                     $(".autoul li.lihover").removeClass("lihover");
     32                 }
     33                 $(".autoul li:visible:eq(0)").addClass("lihover");
     34             }else{//如果为空或者"@"开头
     35                 $(".autoul").hide();
     36                 $(".autoul li:eq(0)").removeClass("lihover");
     37             }
     38 
     39             //把输入的字符填充进提示,有两种情况:1.出现"@"之前,把"@"之前的字符进行填充;2.出现第一次"@"时以及"@"之后还有字符时,不填充
     40             //出现@之前
     41             if($.trim(this.value).match(/[^@]@/)==null){//输入了不含"@"的字符或者"@"开头
     42                 if($.trim(this.value).match(/^@/)==null){
     43 
     44                     //不以"@"开头
     45                     //这里要根据实际html情况进行修改
     46                     $(this).siblings("ul").children("li").children(".ex").text($(this).val());
     47                 }
     48             }else{
     49 
     50                 //输入字符后,第一次出现了不在首位的"@"
     51                 //当首次出现@之后,有2种情况:1.继续输入;2.没有继续输入
     52                 //当继续输入时
     53                 var str = this.value;//输入的所有字符
     54                 var strs = new Array();
     55                 strs = str.split("@");//输入的所有字符以"@"分隔
     56                 $(".ex").text(strs[0]);//"@"之前输入的内容
     57                 var len = strs[0].length;//"@"之前输入内容的长度
     58                 if(this.value.length>len+1){
     59 
     60                     //截取出@之后的字符串,@之前字符串的长度加@的长度,从第(len+1)位开始截取
     61                     var strright = str.substr(len+1);
     62 
     63                     //正则屏蔽匹配反斜杠""
     64                     if(strright.match(/[\]/)!=null){
     65                         strright.replace(/[\]/,"");
     66                         return false;
     67                     }
     68                  
     69                     //遍历li
     70                     $("ul.autoul li").each(function(){
     71 
     72                         //遍历span
     73                         //$(this) li
     74                         $(this).children("span.step").each(function(){
     75 
     76                             //@之后的字符串与邮件后缀进行比较
     77                             //当输入的字符和下拉中邮件后缀匹配并且出现在第一位出现
     78                             //$(this) span.step
     79                             if($("ul.autoul li").children("span.step").text().match(strright)!=null && $(this).text().indexOf(strright)==0){
     80                                 
     81                                 //class showli是输入框@后的字符和邮件列表对比匹配后给匹配的邮件li加上的属性
     82                                 $(this).parent().addClass("showli");
     83                                 //如果输入的字符和提示菜单完全匹配,则去掉高亮和showli,同时提示隐藏
     84                                 
     85                                 if(strright.length>=$(this).text().length){
     86                                         
     87                                     $(this).parent().removeClass("showli").removeClass("lihover").hide();
     88                                 }
     89                             }else{
     90                                 $(this).parent().removeClass("showli");
     91                             }
     92                             if($(this).parent().hasClass("showli")){
     93                                 $(this).parent().show();
     94                                 $(this).parent("li").parent("ul").children("li.showli:eq(0)").addClass("lihover");
     95                             }else{
     96                                 $(this).parent().hide();
     97                                 $(this).parent().removeClass("lihover");
     98                             }
     99                         });
    100                     });
    101 
    102                     //修改
    103                     if(!$(".autoul").children("li").hasClass("showli")){
    104 
    105                         $(".autoul").hide();
    106                     }
    107                 }else{
    108                     //"@"后没有继续输入时
    109                     $(".autoul").children().show();
    110                     $("ul.autoul li").removeClass("showli");
    111                     $("ul.autoul li.lihover").removeClass("lihover");
    112                     $("ul.autoul li:eq(0)").addClass("lihover");
    113                 }
    114             }
    115         }//有效输入按键事件结束
    116 
    117         if(event.keyCode == 8 || event.keyCode == 46){
    118      
    119           $(this).next().children().removeClass("lihover");
    120           $(this).next().children("li:visible:eq(0)").addClass("lihover");
    121         }//删除事件结束  
    122         
    123        if(event.keyCode == 38){
    124          //使光标始终在输入框文字右边
    125           $(this).val($(this).val());
    126        }//方向键↑结束
    127         
    128        if(event.keyCode == 13){
    129         
    130             //keyup时只做菜单收起相关的动作和去掉lihover类的动作,不涉及焦点转移
    131             $(".autoul").hide();
    132             $(".autoul").children().hide();
    133             $(".autoul").children().removeClass("lihover");          
    134        }
    135     });    
    136     
    137     $("#uemail").keydown(function(){
    138 
    139         if(event.keyCode == 40){
    140 
    141             //当键盘按下↓时,如果已经有li处于被选中的状态,则去掉状态,并把样式赋给下一条(可见的)li
    142             if ($("ul.autoul li").is(".lihover")) {
    143 
    144                 //如果还存在下一条(可见的)li的话
    145                 if ($("ul.autoul li.lihover").nextAll().is("li:visible")) {
    146 
    147                     if ($("ul.autoul li.lihover").nextAll().hasClass("showli")) {
    148 
    149                         $("ul.autoul li.lihover").removeClass("lihover")
    150                                 .nextAll(".showli:eq(0)").addClass("lihover");
    151                     } else {
    152 
    153                         $("ul.autoul li.lihover").removeClass("lihover").removeClass("showli")
    154                                 .next("li:visible").addClass("lihover");
    155                         $("ul.autoul").children().show();
    156                     }
    157                 } else {
    158 
    159                     $("ul.autoul li.lihover").removeClass("lihover");
    160                     $("ul.autoul li:visible:eq(0)").addClass("lihover");
    161                 }
    162             } 
    163         }
    164 
    165         if(event.keyCode == 38){
    166 
    167             //当键盘按下↓时,如果已经有li处于被选中的状态,则去掉状态,并把样式赋给下一条(可见的)li
    168             if($("ul.autoul li").is(".lihover")){
    169 
    170                 //如果还存在上一条(可见的)li的话
    171                 if($("ul.autoul li.lihover").prevAll().is("li:visible")){
    172 
    173 
    174                     if($("ul.autoul li.lihover").prevAll().hasClass("showli")){
    175 
    176                         $("ul.autoul li.lihover").removeClass("lihover")
    177                                 .prevAll(".showli:eq(0)").addClass("lihover");
    178                     }else{
    179 
    180                         $("ul.autoul li.lihover").removeClass("lihover").removeClass("showli")
    181                                 .prev("li:visible").addClass("lihover");
    182                         $("ul.autoul").children().show();
    183                     }
    184                 }else{
    185 
    186                     $("ul.autoul li.lihover").removeClass("lihover");
    187                     $("ul.autoul li:visible:eq("+($("ul.autoul li:visible").length-1)+")").addClass("lihover");
    188                 }
    189             }else{
    190 
    191                 //当键盘按下↓时,如果之前没有一条li被选中的话,则第一条(可见的)li被选中
    192                 $("ul.autoul li:visible:eq("+($("ul.autoul li:visible").length-1)+")").addClass("lihover");
    193             }
    194         } 
    195 
    196         if(event.keyCode == 13){                            
    197 
    198             //keydown时完成的两个动作 ①填充 ②判断下拉菜单是否存在,如果不存在则焦点移至密码栏目。注意下拉菜单的收起动作放在keyup事件中。即当从下拉菜单中选择邮箱的时候按回车不会触发焦点转移,而选择完毕菜单收起之后再按回车,才会触发焦点转移事件
    199             if($("ul.autoul li").is(".lihover")) {
    200 
    201                 $("#uemail").val($("ul.autoul li.lihover").children(".ex").text() + "@" + $("ul.autoul li.lihover").children(".step").text());
    202             }
    203 
    204             //把焦点移至密码栏目
    205             if($(".autoul").attr("style") == "display: none;"){
    206     
    207                 $("#upwd").focus();
    208             }
    209         }
    210     });
    211 
    212     
    213     //把click事件修改为mousedown,避免click事件时短暂的失去焦点而触发blur事件
    214     $(".autoli").mousedown(function(){
    215  
    216         $("#uemail").val($(this).children(".ex").text()+$(this).children(".at").text()+$(this).children(".step").text());
    217         $(".autoul").hide();
    218         
    219         //修改
    220         $("#uemail").focus();
    221     }).hover(function(){
    222 
    223         if($("ul.autoul li").hasClass("lihover")){
    224 
    225             $("ul.autoul li").removeClass("lihover");
    226         }
    227         $(this).addClass("lihover");
    228     });
    229 
    230     $("body").click(function(){
    231 
    232         $(".autoul").hide();
    233     });
    234 });
    View Code 

    register.js邮箱代码片段:

    //邮箱下拉js单独引用emailup.js
    $("#uemail").focus(function(){
        
                        var noticeMsg = '用来登陆网站,接收到激活邮件才能完成注册';
                        notice($("#uemailchk"),noticeMsg);
                    })
                    .click(function(){
        
                        var noticeMsg = '用来登陆网站,接收到激活邮件才能完成注册';
                        notice($("#uemailchk"),noticeMsg);
                    })
                    .blur(function(){
                    
                        if(this.value!="" && this.value.match(/^[w-]+(.[w-]+)*@[w-]+(.[w-]+)+$/)!=null){
                        
                            //检测是否被注册
                            $("#uemailchk").html("检测中...").attr("class","loading");
                            //ajax查询用户名是否被注册
                            $.post("./../chkemail.php",{
                            
                                //要传递的数据
                                uemail : $("#uemail").val()
                            },function(data,textStatus){
                                
                                if(data == 0){
                                
                                    var successMsg = '恭喜,该邮箱可以注册';
                                    $("#uemailchk").html(successMsg).attr("class","success");
    
                                    emailval = true;
                                }else if(data == 1){
                                
                                    var errorMsg = '该邮箱已被注册';
                                    error($("#uemailchk"),errorMsg);
                                }else{
                                
                                    var errorMsg = '查询出错,请联系网站管理员';
                                    error($("#uemailchk"),errorMsg);
                                }
                            });
                        }else if(this.value == ""){
                        
                            var errorMsg = '邮箱不能为空';
                            error($("#uemailchk"),errorMsg);
                        }else{
                        
                            var errorMsg = '请填写正确的邮箱地址';
                            $("#uemailchk").html(errorMsg).attr("class","error");
                        }
    });

     提示文字( Chrome下 )

    ①获得焦点时、点击时

    ②输入时

    ③失去焦点为空、格式错误、已被注册、可以注册时分别为

     邮箱功能至此结束。

    密码栏目:

    要求

    ①6-16个个字符,区分大小写(参考豆瓣和网易)

    ②密码不能为同一字符

    ③实时提示是否符合要求以及判断并显示密码强度,:

      1.输入时如果为空(删除时)则用蓝色符号提示不能为空,超过长度时用红色符号

      2.密码满足长度但是为相同字符的组合时:密码太简单,请尝试数字、字母和下划线的组合

      3.密码强度判断有多种规则,有直接依据长度和组合规则作出判断,也有给每种长度和组合设置分数,通过验证实际密码的情况计算出最后分数来判断强弱。在这个模块中采用比较简单的一种形式,也是网易注册采用的方法:

         密码满足长度且全部为不同字母、全部为不同数字或全部为不同符号时为弱:弱:试试字母、数字、符号混搭

         密码满足长度且为数字、字母和符号任意两种组合时为中

         密码满足长度且为数字、字母和符号三种组合时为强

    ④输入时大写提示

    如图:

    register.html 密码栏目HTML代码片段:

    1 <div class="ipt">
    2     <input type="password" name="upwd" id="upwd" value="" placeholder="设置密码" />
    3     <div class="upwdpic">
    4        <span id="upwdchk"></span>
    5        <img id="pictie" />
    6     </div>
    7 </div>

    register.js密码代码片段:

      1 function noticeEasy(){
      2     
      3         //密码全部为相同字符或者为123456,用于keyup时的notice
      4         var noticeMsg = '密码太简单,请尝试数字、字母和下划线的组合';
      5         return notice($("#upwdchk"),noticeMsg);
      6     }
      7 
      8     function errorEasy(){
      9     
     10         //密码全部为相同字符或者为123456,用于blur时的error
     11         var errorMsg = '密码太简单,请尝试数字、字母和下划线的组合';
     12         return error($("#upwdchk"),errorMsg);
     13     }
     14     
     15     //检测密码长度函数
     16     //检测密码长度
     17     function upwdLen(value,func){
     18     
     19         var showMsg = $("#upwdchk");
     20 
     21         if(countLen(value) > 16){
     22                         
     23             var errorMsg = '密码不能超过16个字符';
     24             error(showMsg,errorMsg);
     25             
     26             $("#pictie").hide();
     27         }else if(countLen(value) < 6){
     28         
     29             //使用notice更加友好
     30             var noticeMsg = '密码不能少于6个字符';
     31             notice(showMsg,noticeMsg);
     32 
     33             $("#pictie").hide();
     34         }else if(countLen(value) == 0){
     35         
     36             //使用notice更加友好
     37             var noticeMsg = '密码不能为空';
     38             notice(showMsg,noticeMsg);
     39 
     40             $("#pictie").hide();
     41         }else{
     42         
     43             upwdStrong(value,func);//如果长度不成问题,则调用检测密码强弱
     44         }
     45 
     46         return countLen(value);//返回字符长度
     47     }
     48 
     49     //检测密码强弱
     50     function upwdStrong(value,func){
     51     
     52         var showMsg = $("#upwdchk");
     53 
     54         if(value.match(/^(.)1*$/)!=null || value.match(/^123456$/)){
     55         
     56             //密码全部为相同字符或者为123456,调用函数noticeEasy或errorEasy
     57             func;
     58         }else if(value.match(/^[A-Za-z]+$/)!=null || value.match(/^d+$/)!=null || value.match(/^[^A-Za-z0-9]+$/)!=null){
     59 
     60             //全部为相同类型的字符为弱
     61             var successMsg = '弱:试试字母、数字、符号混搭';
     62             success(showMsg,successMsg);
     63 
     64             //插入强弱条
     65             $("#pictie").show().attr("src","images/weak.jpg");
     66 
     67             pwdval = true;
     68 
     69         }else if(value.match(/^[^A-Za-z]+$/)!=null || value.match(/^[^0-9]+$/)!=null || value.match(/^[a-zA-Z0-9]+$/)!=null){
     70         
     71             //任意两种不同类型字符组合为中强( 数字+符号,字母+符号,数字+字母 )
     72             var successMsg = '中强:试试字母、数字、符号混搭';
     73             success(showMsg,successMsg);
     74 
     75             $("#pictie").show().attr("src","images/normal.jpg");
     76 
     77             pwdval = true;
     78         }else{
     79         
     80             //数字、字母和符号混合
     81             var successMsg = '强:请牢记您的密码';
     82             success(showMsg,successMsg);
     83 
     84             $("#pictie").show().attr("src","images/strong.jpg");
     85 
     86             pwdval = true;
     87         }
     88     }
     89     
     90     $upper = $("<div id="upper">大写锁定已打开</div>");
     91     
     92     $("#upwd").focus(function(){
     93     
     94                     var noticeMsg = '6到16个字符,区分大小写';
     95                     notice($("#upwdchk"),noticeMsg);
     96 
     97                     $("#pictie").hide();
     98             })
     99              .click(function(){
    100             
    101                     var noticeMsg = '6到16个字符,区分大小写';
    102                     notice($("#upwdchk"),noticeMsg);
    103 
    104                     $("#pictie").hide();
    105             }).keydown(function(){
    106             
    107                     //把焦点移至邮箱栏目
    108                     if(event.keyCode == 13){
    109                         
    110                         $("#rupwd").focus();
    111                     }
    112             })
    113              .keyup(function(){
    114              
    115                     //判断大写是否开启
    116                     //输入密码的长度
    117                     var len = this.value.length;                    
    118                     if(len!=0){
    119 
    120                         //当输入的最新以为含有大写字母时说明开启了大写锁定
    121                         if(this.value[len-1].match(/[A-Z]/)!=null){
    122                         
    123                             //给出提示
    124                             $upper.insertAfter($(".upwdpic"));
    125                         }else{
    126                         
    127                             //移除提示
    128                             $upper.remove();
    129                         }
    130                     }else{
    131                     
    132                         //当密码框为空时移除提示
    133                         if($upper){
    134                         
    135                             $upper.remove();
    136                         }
    137                     }//判断大写开启结束
    138             
    139                     //判断长度及强弱
    140                     upwdLen(this.value,noticeEasy());    
    141              })
    142              //keyup事件结束
    143                .blur(function(){
    144                
    145                     upwdLen(this.value,errorEasy());
    146                     //upwdLen函数中部分提示使用notice是为了keyup事件中不出现红色提示,而blur事件中则需使用error标红
    147                     if(this.value == ""){
    148                     
    149                         var errorMsg = '密码不能为空';
    150                         error($("#upwdchk"),errorMsg);
    151 
    152                         $("#pictie").hide();
    153                     }else if(countLen(this.value)<6){
    154                     
    155                         var errorMsg = '密码不能少于6个字符';
    156                         error($("#upwdchk"),errorMsg);
    157 
    158                         $("#pictie").hide();
    159                     }
    160 });

    大写锁定的思路是:判断输入的字符的最新一位是否是大写字母,如果是大写字母,则提示大写锁定键打开。这种方法并不十分准确,网上有一些插件能判断大写锁定,在这里只是简单地做了一下判断。

     提示文字( Chrome下 )

    ①获得焦点、点击时

    ②输入时

         失去焦点时与此效果相同

        失去焦点时与此效果相同

         失去焦点时与此效果相同

                     失去焦点时与此效果相同

    ③失去焦点为空时

    ④出现大写时

    密码栏目至此结束。

    重复密码:失去焦点时判断是否和密码一致

    reister.html代码片段:

    <div class="ipt">
        <input type="password" name="rupwd" id="rupwd" value="" placeholder="确认密码" />
        <span id="rupwdchk"></span>
    </div>

    register.js代码片段:

     1 $("#rupwd").focus(function(){
     2     
     3                     var noticeMsg = '再次输入你设置的密码';
     4                     notice($("#rupwdchk"),noticeMsg);
     5             })
     6                .click(function(){
     7             
     8                     var noticeMsg = '再次输入你设置的密码';
     9                     notice($("#rupwdchk"),noticeMsg);
    10             }).keydown(function(){
    11             
    12                     //把焦点移至邮箱栏目
    13                     if(event.keyCode == 13){
    14                         
    15                         $("#yzm").focus();
    16                     }
    17             })
    18                 .blur(function(){
    19             
    20                     if(this.value == $("#upwd").val() && this.value!=""){
    21                     
    22                         success($("#rupwdchk"),"");
    23 
    24                         rpwdval = true;
    25                     }else if(this.value == ""){
    26                     
    27                         $("#rupwdchk").html("");
    28                     }else{
    29                     
    30                         var errorMsg = '两次输入的密码不一致';
    31                         error($("#rupwdchk"),errorMsg);
    32                     }
    33 });

    提示文字

    ①获得焦点、点击时

    ②失去焦点时和密码不一致、一致时分别为

    至此重复密码结束。

    验证码:不区分大小写

    验证码采用4位,可以包含的字符为数字1-9,字母a-f

    点击验证码和刷新按钮都能刷新验证码

    register.html验证码代码部分:

    1 <div class="ipt iptend">
    2     <input type='text' id='yzm' name='yzm' placeholder="验证码">
    3     <img id='yzmpic' src='' style="cursor:pointer"> <!-- 验证码图片 -->
    4     <a style="cursor:pointer" id='changea'>
    5         <img id="refpic" src="images/ref.jpg" alt="验证码"> <!-- 验证码刷新按钮图片 -->
    6     </a>
    7     <span id='yzmchk'></span>
    8     <input type='hidden' id='yzmHiddenNum' name='yzmHiddenNum' value=''> <!-- 隐藏域,内容是验证码输出的数字,用户输入的字符与其进行对比 -->
    9 </div>

    register.js验证码部分:

      1 //验证码按钮
      2 $("#refpic").hover(function(){
      3         
      4             $(this).attr("src","images/refhover.jpg");
      5         },function(){
      6         
      7             $(this).attr("src","images/ref.jpg");
      8         }).mousedown(function(){
      9         
     10             $(this).attr("src","images/refclick.jpg");
     11         }).mouseup(function(){
     12         
     13             $(this).attr("src","images/ref.jpg");
     14         });
     15         
     16         //生成验证码函数
     17         function showval() {
     18 
     19             num = '';
     20             for (i = 0; i < 4; i++) {
     21 
     22                 tmp = Math.ceil(Math.random() * 15);//Math.ceil上取整;Math.random取0-1之间的随机数
     23                 if (tmp > 9) {
     24                     switch (tmp) {
     25                         case(10):
     26                             num += 'a';
     27                             break;
     28                         case(11):
     29                             num += 'b';
     30                             break;
     31                         case(12):
     32                             num += 'c';
     33                             break;
     34                         case(13):
     35                             num += 'd';
     36                             break;
     37                         case(14):
     38                             num += 'e';
     39                             break;
     40                         case(15):
     41                             num += 'f';
     42                             break;
     43                     }
     44                 } else {
     45                     num += tmp;
     46                 }
     47 
     48                 $('#yzmpic').attr("src","../valcode.php?num="+num);
     49             }
     50             $('#yzmHiddenNum').val(num);
     51         }
     52 
     53         //生成验证码以及刷新验证码
     54         showval();
     55         $('#yzmpic').click(function(){
     56         
     57             showval();
     58         });
     59         $('#changea').click(function(){
     60         
     61             showval();
     62         });
     63 
     64         //验证码检验
     65         function yzmchk(){
     66         
     67             if($("#yzm").val() == ""){
     68             
     69                 var errorMsg = '验证码不能为空';
     70                 error($("#yzmchk"),errorMsg);
     71             }else if($("#yzm").val().toLowerCase()!=$("#yzmHiddenNum").val()){
     72             
     73                 //不区分大小写
     74                 var errorMsg = '请输入正确的验证码';
     75                 error($("#yzmchk"),errorMsg);
     76             }else{
     77             
     78                 success($("#yzmchk"),"");
     79 
     80                 yzmval = true;
     81             }
     82         }
     83 
     84         //验证码的blur事件
     85         $("#yzm").focus(function(){
     86         
     87             var noticeMsg = '不区分大小写';
     88             notice($("#yzmchk"),noticeMsg);
     89         }).click(function(){
     90         
     91             var noticeMsg = '不区分大小写';
     92             notice($("yzmdchk"),noticeMsg);
     93         }).keydown(function(){
     94             
     95             //提交
     96             if(event.keyCode == 13){                
     97                 
     98                 //先检验后提交
     99                 yzmchk();
    100                 formsub();
    101             }
    102         }).blur(function(){
    103         
    104             yzmchk();
    105 });

    valcode.php验证码生成php代码:

     1 <?php 
     2 
     3     header("content-type:image/png");
     4     $num = $_GET['num'];
     5     $imagewidth = 150;
     6     $imageheight = 54;
     7     
     8     //创建图像
     9     $numimage = imagecreate($imagewidth, $imageheight);
    10     
    11     //为图像分配颜色
    12     imagecolorallocate($numimage, 240,240,240); 
    13 
    14     //字体大小
    15     $font_size = 33;
    16     
    17     //字体名称
    18     $fontname = 'arial.ttf';
    19     
    20     //循环生成图片文字
    21     for($i = 0;$i<strlen($num);$i++){
    22         
    23         //获取文字左上角x坐标
    24         $x = mt_rand(20,20) + $imagewidth*$i/5;
    25         
    26         //获取文字左上角y坐标
    27         $y = mt_rand(40, $imageheight);
    28         
    29         //为文字分配颜色
    30         $color = imagecolorallocate($numimage, mt_rand(0,150),  mt_rand(0,150),  mt_rand(0,150));
    31         
    32         //写入文字
    33         imagettftext($numimage,$font_size,0,$x,$y,$color,$fontname,$num[$i]);
    34     }
    35     
    36     //生成干扰码
    37     for($i = 0;$i<2200;$i++){
    38         $randcolor = imagecolorallocate($numimage, rand(200,255), rand(200,255), rand(200,255));
    39         imagesetpixel($numimage, rand()%180, rand()%90, $randcolor);
    40     }
    41     
    42     //输出图片
    43     imagepng($numimage);
    44     imagedestroy($numimage);
    45 ?>

    注:把字体"Arial"放在服务器的相应目录

    提示文字

    ①获得焦点时、点击时

    ②为空且失去焦点时

    ③输入错误、输入正确且失去焦点时分别为

    验证码至此结束。

    使用协议:默认勾选;

    register.html相应代码:

    <span class="fuwu">
            <input type="checkbox" name="agree" id="agree" checked="checked">
            <label for="agree">我同意  <a href="#">" 服务条款  "</a><a href="#">" 网络游戏用户隐私权保护和个人信息利用政策 "</a>
            </label>
    </span>

    register.js相应代码:

     1 if($("#agree").prop("checked") == true){
     2     
     3         fuwuval = true;
     4     }
     5 
     6 $("#agree").click(function(){
     7     
     8         if($("#agree").prop("checked") == true){
     9 
    10             fuwuval = true;
    11             $("#sub").css("background","#69b3f2");
    12         }else{
    13         
    14             $("#sub").css({"background":"#f2f2f2","cursor":"default"});
    15         }    
    16 });

    效果图

    ①勾选之后

    ②未勾选

    提交按钮:检测是否所有栏目都填写正确,否则所有填写错误的栏目将给出错误提示。全部填写正确后提交并且发送验证邮件到注册邮箱中,邮件的验证地址在3日后失效

    首先在register.js开始部分定义几个参数:nameval,emailval,pwdval,rpwdval,yzmval,fuwuval,全部设为0;当相应栏目符合规定之后,把相应的参数设为true。当所有的参数都为true之后,提交至registerChk.php,否则return false。

    register.html相应代码:

    <button type="button" id="sub">立即注册</button>

    register.js相应代码:

    参数设置:

    var nameval,emailval,pwdval,rpwdval,yzmval,fuwuval = 0;

    提交事件:

     1 function formsub(){
     2     
     3         if(nameval != true || emailval!=true || pwdval!=true || rpwdval!=true || yzmval!=true || fuwuval!=true){
     4         
     5             //当邮箱有下拉菜单时点击提交按钮时不会自动收回菜单,因为下面的return false,所以在return false之前判断下拉菜单是否弹出
     6             if(nameval != true && $("#unamechk").val()!=""){
     7             
     8                 var errorMsg = '请输入用户名';
     9                 error($("#namechk"),errorMsg);
    10             }
    11 
    12             if($(".autoul").show()){
    13             
    14                 $(".autoul").hide();
    15             }
    16 
    17             //以下是不会自动获得焦点的栏目如果为空时,点击注册按钮给出错误提示
    18             if($("#uemail").val() == ""){
    19             
    20                 var errorMsg = '邮箱不能为空';
    21                 error($("#uemailchk"),errorMsg);        
    22             }
    23 
    24             if($("#upwd").val() == ""){
    25             
    26                 var errorMsg = '密码不能为空';
    27                 error($("#upwdchk"),errorMsg);        
    28             }
    29 
    30             if($("#rupwd").val() == ""){
    31             
    32                 var errorMsg = '请再次输入你的密码';
    33                 error($("#rupwdchk"),errorMsg);        
    34             }
    35 
    36             if($("#yzm").val() == ""){
    37             
    38                 var errorMsg = '验证码不能为空';
    39                 error($("#yzmchk"),errorMsg);        
    40             }
    41 
    42         }else{
    43         
    44             $("#register-form").submit();
    45         }
    46     }
    47 
    48     $("#sub").click(function(){
    49         
    50         formsub();
    51 });

    显示效果

    有栏目为空时点击提交按钮

    注册以及发送邮件

    使用了Zend Framework( 1.11.11 )中的zend_email组件。Zend Framework的下载地址是:https://packages.zendframework.com/releases/ZendFramework-1.11.11/ZendFramework-1.11.11.zip。在Zend Framework根目录下library路径下,剪切Zend文件至服务器下,在注册页面中引入Zend/Mail/Transport/Smtp.php和Zend/Mail.php两个文件。

    当点击提交按钮时,表单将数据提交至register_chk.php,然后页面在当前页跳转至register_back.html,通知用户注册结果并且进邮箱激活。

    验证邮箱的地址参数使用用户名和一个随机生成的key。

    register_chk.php

     1 <?php 
     2 
     3     include_once 'conn/conn.php';
     4     include_once 'Zend/Mail/Transport/Smtp.php';
     5     include_once 'Zend/Mail.php';
     6     
     7     //激活key,生成的随机数
     8     $key = md5(rand());
     9     
    10     //先写入数据库,再发邮件
    11     //写入数据库
    12     //判断是否开启magic_quotes_gpc
    13     if(get_magic_quotes_gpc()){
    14     
    15         $postuname = $_POST['uname'];
    16         $postupwd = $_POST['upwd'];
    17         $postuemail = $_POST['uemail'];
    18     }else{
    19         
    20         $postuname = addslashes($_POST['uname']);
    21         $postupwd = addslashes($_POST['upwd']);
    22         $postuemail = addslashes($_POST['uemail']);
    23     }
    24 
    25     function check_input($value){
    26     
    27         // 如果不是数字则加引号
    28         if (!is_numeric($value)){
    29         
    30             $value = mysql_real_escape_string($value);
    31         }
    32         return $value;
    33     }
    34     
    35     $postuname = check_input($postuname);
    36     $postupwd = check_input($postupwd);
    37     $postuemail = check_input($postuemail);
    38 
    39     $sql = "insert into user(uname,upwd,uemail,activekey)values('".trim($postuname)."','".md5(trim($postupwd))."','".trim($postuemail)."','".$key."')";
    40 
    41     $num = $conne->uidRst($sql);
    42     if($num == 1){
    43         
    44         //插入成功时发送邮件
    45         //用户激活链接
    46         $url = 'http://'.$_SERVER['HTTP_HOST'].'/php/myLogin/activation.php';
    47         //urlencode函数转换url中的中文编码
    48         //带反斜杠
    49         $url.= '?name='.urlencode(trim($postuname)).'&k='.$key;
    50         //定义登录使用的邮箱
    51         $envelope = 'dee1566@126.com';
    52         
    53         //激活邮件的主题和正文
    54         $subject = '激活您的帐号';
    55         $mailbody = '注册成功,<a href="'.$url.'" target="_blank">请点击此处激活帐号</a>';
    56         
    57         //发送邮件
    58         //SMTP验证参数
    59         $config = array(
    60                 
    61                 'auth'=>'login',
    62                 'port' => 25,
    63                 'username'=>'dee1566@126.com',
    64                 'password'=>'你的密码'
    65                 );
    66         
    67         //实例化验证的对象,使用gmail smtp服务器
    68         $transport = new Zend_Mail_Transport_Smtp('smtp.126.com',$config);
    69         $mail = new Zend_Mail('utf-8');
    70         
    71         $mail->addTo($_POST['uemail'],'获取用户注册激活链接');
    72         $mail->setFrom($envelope,'发件人');
    73         $mail->setSubject($subject);
    74         $mail->setBodyHtml($mailbody);
    75         $mail->send($transport);
    76 
    77         echo "<script>self.location="templets/register_back.html";</script>";
    78 
    79     }else{
    80     
    81         echo "<script>self.location="templets/register_back.html?error=1";</script>";
    82     }
    83 ?>

    邮箱中收取的邮件截图:

    然后点击邮箱中的链接进行激活,把数据库中的active设置为1。

    activation.php

     1 <?php 
     2 session_start();
     3 header('Content-type:text/html;charset=utf-8');
     4 include_once 'conn/conn.php';
     5 
     6 $table = "user";
     7 
     8 if(!empty($_GET['name']) && !is_null($_GET['name'])){
     9                     
    10     //urlencode会对字符串进行转义。所以这里要进行处理
    11     if(get_magic_quotes_gpc()){
    12     
    13         $getname = stripslashes(urldecode($_GET['name']));
    14     }else{
    15     
    16         $getname = urldecode($_GET['name']);
    17     }
    18 
    19     //urldecode反转url中的中文编码
    20     $sql = "select * from ".$table." where uname='".$getname."' and activekey='".$_GET['k']."'";
    21 
    22     $num = $conne->getRowsNum($sql);
    23     if($num>0){
    24         
    25         $rs = $conne->getRowsRst($sql);    
    26 
    27         //此时数据库里的字符串是不会带反斜杠的    
    28         //因此要为下面的SQL语句加上反斜杠
    29         $rsname = addslashes($rs['uname']);
    30 
    31         $upnum = $conne->uidRst("update ".$table." set active = 1 where uname = '".$rsname."' and activekey = '".$rs['activekey']."'");
    32 
    33         if($upnum>0){
    34             
    35             $_SESSION['name'] = urldecode($getname);
    36             echo "<script>alert('您已成功激活');window.location.href='main.php';</script>";
    37         }else{
    38             
    39             echo "<script>alert('您已经激活过了');window.location.href='main.php';</script>";
    40         }
    41     }else{
    42         
    43         echo "<script>alert('激活失败');window.location.href='templets/register.html';</script>";
    44     }
    45 }
    46 
    47 ?>

    关于注册成功后的邮件页和跳转页,这里不做了。 

    关于数据库防注入的几种方式magic_quote_gpc,addslashes/stripslashes,mysql_real_eascpae_string,我做了一张表格

     

    数据库设计:

    user表

    1 create table user (id int primary key auto_increment,
    2 uname varchar(14) not null default '',
    3 upwd char(32) not null default '',
    4 uemail varchar(50) not null default '',
    5 active tinyint(4) default '0',
    6 activekey char(32) not null defalut ''
    )engine=innodb default charset=utf8

    说明:md5的长度是32。

    模块的目录结构如下:

    ROOT:
    ├─conn
    │ ├─conn.php

    ├─templets
    │ ├─css
    │ │ ├─common.css
    │ │ ├─register.css
    │ │
    │ ├─images
    │ │
    │ └─js
    │ ├─jquery-1.8.3.min.js
    │ ├─register.js
    │ ├─emailup.js

    ├─chkname.php
    ├─chkemail.php
    ├─valcode.php
    ├─register_chk.php
    ├─activation.php
    ├─arial.ttf

    └─Zend

    模块至此结束。

    作者:小dee
    说明:作者写博目的是记录开发过程,积累经验,便于以后工作参考。
    如需转载,请在文章页面保留此说明并且给出原文链接。谢谢!
  • 相关阅读:
    css 实现的纸张卷曲效果
    前端如何优化代码&前端web安全
    React native
    君士坦丁堡分叉引起的安全问题
    不用外部插件启用u盘ntfs写功能
    使用ubuntu搭建时间机器备份服务
    从一起“盗币”事件再谈合约安全问题
    如何让你的项目同时支持go vendor和go module
    golang plugin的依赖问题
    Plasma Cash合约解读
  • 原文地址:https://www.cnblogs.com/dee0912/p/3950093.html
Copyright © 2020-2023  润新知