<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    注冊表單驗證(轉,如有侵權請聯絡我馬上刪除)

    文本框:
圖3.1  實例運行效果網站在注冊新用戶過程中,需要驗證很多內容。例如,用戶名是否已存在,E-mail是否已被人使用,驗證碼是否正確等。傳統方式是使用客戶端JavaScript做初步驗證,用戶提交表單后在服務器端做進一步驗證。如果用戶輸入的內容有錯誤,會返回注冊頁面,提示用戶修改。使用了Ajax技術后,很多原來必須提交到服務器才能驗證的內容,可以在不刷新頁面的情況下直接驗證。本例就演示了這個過程,實例運行效果如圖3.1所示。

    3.1.1  技術要點

    本例中要驗證的內容有用戶名、密碼、E-mail和驗證碼4部分內容。但從技術實現上主要有3種形式,下面來一一介紹。

    1.驗證用戶名和E-mail是否已存在

    在用戶輸入用戶名或E-mail之后,使用XMLHttpRequest對象將用戶輸入的信息發送給服務器。服務器判斷是否存在同名用戶或E-mail地址。驗證完畢后將信息反饋給客戶端,由客戶端顯示驗證結果。這樣用戶在未提交整個表單前,就可以知道輸入的用戶名或E-mail是否可以使用。

    2.密碼驗證

    密碼驗證比較簡單,不需要到服務器判斷。只需在客戶端對兩次輸入的密碼進行比對,當輸入一致時通過驗證,否則提示用戶密碼有誤。

    3.生成驗證碼與校驗過程

    驗證碼主要是防止惡意用戶使用工具自動進行批量注冊,搶占用戶名。其基本原理是在服務器生成一個隨機數字,并放入用戶session中。客戶端顯示使用該隨機數字生成的圖片,用戶按照圖片內容輸入驗證碼。最后將用戶的輸入與session中的驗證碼進行比對,如果一致則驗證成功。本例中使用Java類庫中圖像API生成包含三位數字驗證碼的PNG格式圖片。具體的代碼可參考code.jsp。

    4.將驗證函數封裝在Checker對象中

    以上3種方式的驗證函數都封裝在一個Checker對象中。里面包含的checkNode函數對應用戶名和E-mail驗證,以及驗證碼校驗。checkPassword函數對應密碼驗證。所有的驗證結果第一個字符是數字0或1,分別表示驗證失敗或成功。后面緊跟驗證結果的詳細文字說明。showInfo函數根據驗證結果進行不同樣式的顯示。

    3.1.2  數據庫設計

    本實例使用名為users的數據庫表,包含的數據如圖3.2所示。具體的創建數據表語句如下:

    CREATE TABLE 'users' (

      'id' int(11) NOT NULL auto_increment,

      'username' varchar(255) NOT NULL,

      'password' varchar(255) NOT NULL,

      'E-mail' varchar(255) NOT NULL,

      PRIMARY KEY  ('id')

    )

    圖3.2  表users包含的數據

    本實例共包括4個文件:用戶操作界面register.html,服務器端響應文件checker.jsp,驗證碼圖片生成文件code.jsp,以及JavaScript文件checker.js。

    3.1.3  用戶操作界面register.html

    頁面包含操作界面樣式以及注冊表單。表單中各元素通過onblur(失去焦點)事件觸發驗證函數。每個表單元素對應一個div,用于顯示驗證結果。

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

    <head>

    <meta http-equiv="Content-type" content="text/html; charset=utf-8">

    <title>注冊表單驗證</title>

    <style type="text/css">

    /* 頁面字體樣式 */

    body, td, input {

        font-family:Arial;

        font-size:12px;

    }

    /* 表格基本樣式 */

    table.default {

        border-collapse:collapse;

        width:300px;

    }

    /* 表格單元格樣式 */

    table.default td {

        border:1px solid black;

        padding:3px;

    }

    /* 列頭樣式 */

    table.default td.item {

        background:#006699;

        color:#fff;

    }

    /* 正常信息樣式 */

    div.ok {

        color:#006600;

    }

    /* 警告信息樣式 */

    div.warning {

        color:#FF0000;

    }

    </style>

    <!-- 引入外部checker.js文件 -->

    <script type="text/javascript" src="checker.js"></script>

    </head>

    <body>

    <h1>注冊表單驗證</h1>

    <form method="post" action="register.jsp"

           onsubmit="alert('后面的注冊過程與傳統方式相同。');return false">

    <table class="default">

    <tr>

        <td class="item" width="30%">用戶名:</td>

        <td width="70%">

            <input type="text" name="username" id="username" onblur="Checker.checkNode(this)">

            <div id="usernameCheckDiv" class="warning">請輸入用戶名。</div>

        </td>

    </tr>

    <tr>

        <td class="item">密碼:</td>

        <td>

            <input type="password" name="password" id="password" onblur="Checker.checkPassword()">

            <div id="passwordCheckDiv" class="warning">請輸入密碼。</div>

        </td>

    </tr>

    <tr>

        <td class="item">密碼驗證:</td>

        <td>

            <input type="password" name="password2" id="password2" onblur="Checker.checkPassword()">

            <div id="password2CheckDiv" class="warning">請再次輸入密碼。</div>

        </td>

    </tr>

    <tr>

        <td class="item">E-mail:</td>

        <td>

            <input type="text" name="E-mail" id="E-mail" onblur="Checker.checkNode(this)">

            <div id="E-mailCheckDiv" class="warning">請輸入郵件地址。</div>

        </td>

    </tr>

    <tr>

        <td class="item">驗證碼:</td>

        <td>

            <input type="text" name="code" id="code" size="5"

                    onblur="Checker.checkNode(this)">

            <img src="code.jsp" width="40" height="20" border="0" alt="">

            <div id="codeCheckDiv" class="warning">請輸入圖片中的數字驗證碼。</div>

        </td>

    </tr>

    <tr>

        <td colspan="2" align="center">

            <input type="submit" value="注冊">

        </td>

    </tr>

    </table>

    </form>

    </body>

    </html>

    3.1.4  服務器端響應文件checker.jsp

    服務器端響應文件主要包含兩類驗證,根據用戶提交的表單元素名確定驗證方式。如果表單元素名是userName或E-mail,則進行數據查詢,判斷是否存在相同信息。如果是code,則直接通過對比session中的驗證碼進行判斷。

    <%@ page contentType="text/plain; charset=UTF-8"%>

    <%@ page language="java"%>

    <%@ page import="java.sql.*,ajax.db.DBUtils"%>

    <%!

        //查詢數據庫是否存在相同信息

        boolean hasSameValue(String name, String value) {

            boolean result = false;                                                                 //保存檢測結果

            //定義查詢數據庫的SQL語句

            String sql = "select * from users where " + name + " = ?";

            Connection conn = null;                                                     //聲明Connection對象

            PreparedStatement pstmt = null;                                               //聲明PreparedStatement對象

            ResultSet rs = null;                                                              //聲明ResultSet對象

            try {

                conn = DBUtils.getConnection();                              //獲取數據庫連接

                pstmt = conn.prepareStatement(sql);                      //根據sql創建PreparedStatement

                pstmt.setString(1, value);                                           //設置參數

                rs = pstmt.executeQuery();                                        //執行查詢,返回結果集

                //根據結果集是否存在決定查詢結果

                if (rs.next()) {

                    result = true;

                } else {

                    result = false;

                }

            } catch (SQLException e) {

                System.out.println(e.toString());

            } finally {

                DBUtils.close(rs);                                                         //關閉結果集

                DBUtils.close(pstmt);                                                  //關閉PreparedStatement

                DBUtils.close(conn);                                                   //關閉連接

            }

            return result;

        }

    %>

    <%

        out.clear();                                                                                     //清空當前的輸出內容(空格和換行符)

        request.setCharacterEncoding("UTF-8");                               //設置請求體字符編碼格式為UTF-8

        String name = request.getParameter("name");                     //獲取name參數

        String value = request.getParameter("value");                      //獲取value參數

        String info = null;                                                                         //用于保存提示對象的名稱

        //如果需要判斷的是驗證碼,采用session方式驗證

        if ("code".equals(name)) {

            //獲取session中保存的驗證碼

            String sessionCode = (String) session.getAttribute("_CODE_");

            //根據對比結果輸出響應信息

            if (value != null && value.equals(sessionCode)) {

                out.print("1驗證碼正確。");

            } else {

                out.print("0驗證碼錯誤。");

            }

        } else {

            //根據name變量確定提示對象的名稱

            if ("username".equals(name)) {

                info = "用戶名";

            } else if ("E-mail".equals(name)) {

                info = "郵件地址";

            }

            //根據是否存在相同信息輸出對應的響應

            if (hasSameValue(name, value)) {

                out.print("0該" + info + "已存在,請更換" + info + "。");

            } else {

                out.print("1該" + info + "可正常使用。");

            }

        }

    %>

    3.1.5  驗證碼生成文件code.jsp

    生成驗證碼要注意頁首contentType的設置為image/png。主要使用了awt組件和imageio組件中相關的API進行圖片生成,隨機數是使用java.util.Random類生成的。詳細的過程參考以下代碼:

    <%@ page contentType="image/png" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %><%

    //設置頁面不緩存

    response.setHeader("Pragma","No-cache");

    response.setHeader("Cache-Control","no-cache");

    response.setDateHeader("Expires", 0);

    int width=40;                                                                                         //設置圖片寬度

    int height=20;                                                                                        //設置圖片高度

    //創建緩存圖像

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    Graphics g = image.getGraphics();                                                  //獲取圖形

    g.setColor(new Color(000, 102, 153));                                           //設置背景色

    g.fillRect(0, 0, width, height);                                                             //填充背景

    g.setColor(new Color(000, 000, 000));                                           //設置邊框顏色

    g.drawRect(0, 0, width-1, height-1);                                                 //繪制邊框

    g.setFont(new Font("Arial", Font.PLAIN, 16));                                //設定字體

    Random random = new Random();                                                 //生成隨機類

    //隨機產生3位數字驗證碼

    StringBuffer sbRan = new StringBuffer();                                       //保存驗證碼文本

    for (int i=0; i<3; i++){

        String ranNum = String.valueOf(random.nextInt(10));

        sbRan.append(ranNum);

        //將驗證碼繪制到圖像中

        g.setColor(new Color(255, 255, 255));

        g.drawString(ranNum, 10 * i + 5, 16);

    }

    g.dispose();                                                                                           //部署圖像

    session.setAttribute("_CODE_", sbRan.toString());                       //將驗證碼保存在session對象中供對比

    ImageIO.write(image, "PNG", response.getOutputStream());              //輸出圖像到頁面

    %>

    3.1.6  JavaScript文件checker.js

    所有的驗證函數都封裝在一個名為Checker的對象中,獨立存在于checker.js文件里。函數調用流程如圖3.3所示。

    圖3.3  函數調用流程

    var Checker = new function() {

        this._url = "checker.jsp";                                                                      //服務器端文件地址

        this._infoDivSuffix = "CheckDiv";                                                      //提示信息div的統一后綴

        //檢查普通輸入信息

        this.checkNode = function(_node) {

            var nodeId = _node.id;                                                                          //獲取節點id

            if (_node.value!="") {

                var xmlHttp=this.createXmlHttp();                                               //創建XmlHttpRequest對象

                xmlHttp.onreadystatechange = function() {

                    if (xmlHttp.readyState == 4) {

                        //調用showInfo方法顯示服務器反饋信息

                        Checker.showInfo(nodeId + Checker._infoDivSuffix,

                                            xmlHttp.responseText);

                    }

                }

                xmlHttp.open("POST", this._url, true);

                xmlHttp.setRequestHeader(

                                         "Content-type","application/x-www-form-urlencoded");

                xmlHttp.send("name=" + encodeURIComponent(_node.id) +

                             //發送包含用戶輸入信息的請求體

                             "&value=" + encodeURIComponent(_node.value));

            }

        }

        //顯示服務器反饋信息

        this.showInfo = function(_infoDivId, text) {

            var infoDiv = document.getElementById(_infoDivId); //獲取顯示信息的div

            var status = text.substr(0,1);                                               //反饋信息的第一個字符表示信息類型

            if (status == "1") {

                infoDiv.className = "ok";                                         //檢查結果正常

            } else {

                infoDiv.className = "warning";                               //檢查結果需要用戶修改

            }

            infoDiv.innerHTML = text.substr(1);                                 //寫回詳細信息

        }

        //用于創建XMLHttpRequest對象

        this.createXmlHttp = function() {

            var xmlHttp = null;

            //根據window.XMLHttpRequest對象是否存在使用不同的創建方式

            if (window.XMLHttpRequest) {

               xmlHttp = new XMLHttpRequest();                             //FireFox、Opera等瀏覽器支持的創建方式

            } else {

               xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");//IE瀏覽器支持的創建方式

            }

            return xmlHttp;

        }

        //檢查兩次輸入的密碼是否一致

        this.checkPassword = function() {

            var p1 = document.getElementById("password").value;                //獲取密碼

            var p2 = document.getElementById("password2").value;             //獲取驗證密碼

            //當兩部分密碼都輸入完畢后進行判斷

            if (p1 != "" && p2 != "") {

                if (p1 != p2) {

                    this.showInfo("password2" + Checker._infoDivSuffix,

                                     "0密碼驗證與密碼不一致。");

                } else {

                    this.showInfo("password2" + Checker._infoDivSuffix, "1");

                }

            } else if (p1 != null) {

                this.showInfo("password" + Checker._infoDivSuffix, "1");

            }

        }

    }

    3.1.7  小結

    表單驗證在網站中是很常見的內容,可以說只要是用到表單的地方,十有八九需要進行內容驗證。當遇到需要提交給服務器才能驗證的字段時,使用Ajax技術是一個非常好的選擇。本例雖然只講解了用戶注冊的表單驗證,但其基本思想和實現技術可以推廣到各種類型的表單驗證中去。

    posted on 2009-04-20 12:55 MichaelLee 閱讀(2041) 評論(2)  編輯  收藏 所屬分類: JavaScript

    評論

    # re: 注冊表單驗證(轉,如有侵權請聯絡我馬上刪除) 2010-08-21 16:53 sdfas

    asdfasdfasdf  回復  更多評論   

    # re: 注冊表單驗證(轉,如有侵權請聯絡我馬上刪除) 2010-08-21 16:53 sdfas

    sdfasdfa  回復  更多評論   


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2010年8月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    導航

    統計

    公告

    ====Michael Lee====
    =Java Sofware Engineer=
    =Work @ Beijing=
    ---再煩,也別忘微笑;再急,也要注意語氣;再苦,也別忘堅持;再累,也要愛自己!---
    ---低調做人,你會一次比一次穩健;高調做事,你會一次比一次優秀---
    ---成功的時候不要忘記過去;失敗的時候不要忘記還有未來---

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品乱码久久久久久下载| 99久久国产免费-99久久国产免费 99久久国产免费中文无字幕 | 国产免费不卡v片在线观看| 中文日本免费高清| 精品亚洲视频在线| 亚洲一区二区三区免费在线观看 | 亚洲中文字幕无码中文字| 亚洲av日韩av激情亚洲| 狠狠色婷婷狠狠狠亚洲综合| 在线免费观看一级片| 久久笫一福利免费导航| 午夜精品射精入后重之免费观看| 一二三区免费视频| 国产亚洲日韩在线a不卡| 亚洲av无码片区一区二区三区| 亚洲一区二区三区四区在线观看| 亚洲精品无码你懂的网站| 四虎影视免费永久在线观看| 国产香蕉九九久久精品免费| 黄色免费网站网址| 蜜桃成人无码区免费视频网站| 水蜜桃视频在线观看免费播放高清 | 全黄大全大色全免费大片| 国产福利在线观看永久免费| 美女被爆羞羞网站在免费观看| 亚洲精品日韩一区二区小说| 中文无码亚洲精品字幕| 亚洲一区二区三区在线| 亚洲成a人片在线观| 亚洲国产综合在线| 亚洲专区一路线二| 亚洲香蕉久久一区二区三区四区| 亚洲国产品综合人成综合网站| 精品日韩亚洲AV无码一区二区三区 | 国产人成免费视频| 日本无卡码免费一区二区三区| 女人让男人免费桶爽30分钟| 手机看片久久国产免费| 免费v片在线观看无遮挡| 免费大黄网站在线观看| 亚洲中文字幕无码专区|