原文地址: http://www.blueidea.com/tech/web/2004/2360.asp
表單的驗證一直是網頁設計者頭痛的問題,表單驗證類 Validator就是爲解決這個問題而寫的,旨在使設計者從紛繁複雜的表單驗證中解放出來,把精力集中於網頁的設計和功能上的改進上。
Validator是基於JavaScript技術的僞靜態類和對象的自定義屬性,可以對網頁中的表單項輸入進行相應的驗證,允許同一頁面中同時驗證多個表單,熟悉接口之後也可以對特定的表單項甚至僅僅是某個字符串進行驗證。因爲是僞靜態類,所以在調用時不需要實例化,直接以"類名+.語法+屬性或方法名"來調用。此外,Validator還提供3種不同的錯誤提示模式,以滿足不同的需要。
Validator目前可實現的驗證類型有:
[JavaScript] 版
Validator目前可實現的驗證類型有:
1.是否爲空;
2.中文字符;
3.雙字節字符
4.英文;
5.數字;
6.整數;
7.實數;
8.Email地址;
9.使用HTTP協議的網址;
10.電話號碼;
11.貨幣;
12.手機號碼;
13.郵政編碼;
14.身份證號碼(1.05增強);
15.QQ號碼;
16.日期;
17.符合安全規則的密碼;
18.某項的重複值;
19.兩數的關係比較;
20.判斷輸入值是否在(n, m)區間;
21.輸入字符長度限制(可按字節比較);
22.對於具有相同名稱的單選按鈕的選中判斷;
23.限制具有相同名稱的多選按鈕的選中數目;
24.自定義的正則表達式驗證;
25.文件上傳格式過濾(1.04)
運行環境(客戶端):
在Windows Server 2003下用IE6.0+SP1和Mozilla Firefox 1.0測試通過;
在Lunix RedHat 9下的Netscape測試通過;
對於客戶端的表單驗證,這個基於JavaScript編寫的Validator基本上都可以滿足,具體可以下載CHM文件:Validator.CHM下載
示例:
<title>表單驗證類 Validator v1.05</title>
<style>
body,td{font:normal 12px Verdana;color:#333333}
input,textarea,select,td{font:normal 12px Verdana;color:#333333;border:1px solid #999999;background:#ffffff}
table{border-collapse:collapse;}
td{padding:3px}
input{height:20;}
textarea{width:80%;height:50px;overflow:auto;}
form{display:inline}
</style>
<table align="center">
<form name="theForm" id="demo" method="get" onSubmit="return Validator.Validate(this,2)">
<tr>
<td>身份證號:</td><td><input name="Card" dataType="IdCard" msg="身份證號錯誤"></td>
</tr>
<tr>
<td>真實姓名:</td><td><input name="Name" dataType="Chinese" msg="真實姓名只允許中文"></td>
</tr>
<tr>
<td>ID:</td><td><input name="username" dataType="Username" msg="ID名不符合規定"></td>
</tr>
<tr>
<td>英文名:</td><td><input name="Nick" dataType="English" require="false" msg="英文名只允許英文字母"></td>
</tr>
<tr>
<td>主頁:</td><td><input name="Homepage" require="false" dataType="Url" msg="非法的Url"></td>
</tr>
<tr>
<td>密碼:</td><td><input name="Password" dataType="SafeString" msg="密碼不符合安全規則" type="password"></td>
</tr>
<tr>
<td>重複:</td><td><input name="Repeat" dataType="Repeat" to="Password" msg="兩次輸入的密碼不一致" type="password"></td>
</tr>
<tr>
<td>信箱:</td><td><input name="Email" dataType="Email" msg="信箱格式不正確"></td>
</tr>
<tr>
<td>信箱:</td><td><input name="Email" dataType="Repeat" to="Email" msg="兩次輸入的信箱不一致"></td>
</tr>
<tr>
<td>QQ:</td><td><input name="QQ" require="false" dataType="QQ" msg="QQ號碼不存在"></td>
</tr>
<tr>
<td>身份證:</td><td><input name="Card" dataType="IdCard" msg="身份證號碼不正確"></td>
</tr>
<tr>
<td>年齡:</td><td><input name="Year" dataType="Range" msg="年齡必須在18~28之間" min="18" max="28"></td>
</tr>
<tr>
<td>年齡1:</td><td><input name="Year1" require="false" dataType="Compare" msg="年齡必須在18以上" to="18" operator="GreaterThanEqual"></td>
</tr>
<tr>
<td>電話:</td><td><input name="Phone" require="false" dataType="Phone" msg="電話號碼不正確"></td>
</tr>
<tr>
<td>手機:</td><td><input name="Mobile" require="false" dataType="Mobile" msg="手機號碼不正確"></td>
</tr>
<tr>
<td>生日:</td><td><input name="Birthday" dataType="Date" format="ymd" msg="生日日期不存在"></td>
</tr>
<tr>
<td>郵政編碼:</td><td><input name="Zip" dataType="Custom" regexp="^[1-9]\d{5}$" msg="郵政編碼不存在"></td>
</tr>
<tr>
<td>郵政編碼:</td><td><input name="Zip1" dataType="Zip" msg="郵政編碼不存在"></td>
</tr>
<tr>
<td>操作系統:</td><td><select name="Operation" dataType="Require" msg="未選擇所用操作系統" ><option value="">選擇您所用的操作系統</option><option value="Win98">Win98</option><option value="Win2k">Win2k</option><option value="WinXP">WinXP</option></select></td>
</tr>
<tr>
<td>所在省份:</td><td>廣東<input name="Province" value="1" type="radio">陝西<input name="Province" value="2" type="radio">浙江<input name="Province" value="3" type="radio">江西<input name="Province" value="4" type="radio" dataType="Group" msg="必須選定一個省份" ></td>
</tr>
<tr>
<td>愛好:</td><td>運動<input name="Favorite" value="1" type="checkbox">上網<input name="Favorite" value="2" type="checkbox">聽音樂<input name="Favorite" value="3" type="checkbox">看書<input name="Favorite" value="4" type="checkbox"" dataType="Group" min="2" max="3"
msg="必須選擇2~3種愛好"></td>
</tr>
<td>自我介紹:</td><td><textarea name="Description" dataType="Limit" max="10" msg="自我介紹內容必須在10個字之內">中文是一個字</textarea></td>
</tr>
<td>自傳:</td><td><textarea name="History" dataType="LimitB" min="3" max="10" msg="自傳內容必須在[3,10]個字節之內">中文是兩個字節t</textarea></td>
</tr>
<tr>
<td>相片上傳:</td><td><input name="up" dataType="Filter" msg="非法的文件格式" type="file" accept="jpg, gif, png"></td>
</tr>
<tr>
<td colspan="2"><input name="Submit" type="submit" value="確定提交"><input onClick="Validator.Validate(document.getElementById('demo'))" value="檢驗模式1" type="button"><input onClick="Validator.Validate(document.getElementById('demo'),2)" value="檢驗模式2" type="button"><input
onClick="Validator.Validate(document.getElementById('demo'),3)" value="檢驗模式3" type="button"></td>
</tr>
</form>
</table>
<script>
/*************************************************
Validator v1.05
code by 我佛山人
[email protected]
*************************************************/
Validator = {
Require : /.+/,
Email : /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
Phone : /^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/,
Mobile : /^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$/,
Url : /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/,
IdCard : "this.IsIdCard(value)",
Currency : /^\d+(\.\d+)?$/,
Number : /^\d+$/,
Zip : /^[1-9]\d{5}$/,
QQ : /^[1-9]\d{4,8}$/,
Integer : /^[-\+]?\d+$/,
Double : /^[-\+]?\d+(\.\d+)?$/,
English : /^[A-Za-z]+$/,
Chinese : /^[\u0391-\uFFE5]+$/,
Username : /^[a-z]\w{3,}$/i,
UnSafe : /^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\'\"]*)|.{0,5})$|\s/,
IsSafe : function(str){return !this.UnSafe.test(str);},
SafeString : "this.IsSafe(value)",
Filter : "this.DoFilter(value, getAttribute('accept'))",
Limit : "this.limit(value.length,getAttribute('min'), getAttribute('max'))",
LimitB : "this.limit(this.LenB(value), getAttribute('min'), getAttribute('max'))",
Date : "this.IsDate(value, getAttribute('min'), getAttribute('format'))",
Repeat : "value == document.getElementsByName(getAttribute('to'))[0].value",
Range : "getAttribute('min') < (value|0) && (value|0) < getAttribute('max')",
Compare : "this.compare(value,getAttribute('operator'),getAttribute('to'))",
Custom : "this.Exec(value, getAttribute('regexp'))",
Group : "this.MustChecked(getAttribute('name'), getAttribute('min'), getAttribute('max'))",
ErrorItem : [document.forms[0]],
ErrorMessage : ["以下原因導致提交失敗:\t\t\t\t"],
Validate : function(theForm, mode){
var obj = theForm || event.srcElement;
var count = obj.elements.length;
this.ErrorMessage.length = 1;
this.ErrorItem.length = 1;
this.ErrorItem[0] = obj;
for(var i=0;i<count;i++){
with(obj.elements[i]){
var _dataType = getAttribute("dataType");
if(typeof(_dataType) == "object" || typeof(this[_dataType]) == "undefined") continue;
this.ClearState(obj.elements[i]);
if(getAttribute("require") == "false" && value == "") continue;
switch(_dataType){
case "IdCard" :
case "Date" :
case "Repeat" :
case "Range" :
case "Compare" :
case "Custom" :
case "Group" :
case "Limit" :
case "LimitB" :
case "SafeString" :
case "Filter" :
if(!eval(this[_dataType])) {
this.AddError(i, getAttribute("msg"));
}
break;
default :
if(!this[_dataType].test(value)){
this.AddError(i, getAttribute("msg"));
}
break;
}
}
}
if(this.ErrorMessage.length > 1){
mode = mode || 1;
var errCount = this.ErrorItem.length;
switch(mode){
case 2 :
for(var i=1;i<errCount;i++)
this.ErrorItem[i].style.color = "red";
case 1 :
alert(this.ErrorMessage.join("\n"));
this.ErrorItem[1].focus();
break;
case 3 :
for(var i=1;i<errCount;i++){
try{
var span = document.createElement("SPAN");
span.id = "__ErrorMessagePanel";
span.style.color = "red";
this.ErrorItem[i].parentNode.appendChild(span);
span.innerHTML = this.ErrorMessage[i].replace(/\d+:/,"*");
}
catch(e){alert(e.description);}
}
this.ErrorItem[1].focus();
break;
default :
alert(this.ErrorMessage.join("\n"));
break;
}
return false;
}
return true;
},
limit : function(len,min, max){
min = min || 0;
max = max || Number.MAX_VALUE;
return min <= len && len <= max;
},
LenB : function(str){
return str.replace(/[^\x00-\xff]/g,"**").length;
},
ClearState : function(elem){
with(elem){
if(style.color == "red")
style.color = "";
var lastNode = parentNode.childNodes[parentNode.childNodes.length-1];
if(lastNode.id == "__ErrorMessagePanel")
parentNode.removeChild(lastNode);
}
},
AddError : function(index, str){
this.ErrorItem[this.ErrorItem.length] = this.ErrorItem[0].elements[index];
this.ErrorMessage[this.ErrorMessage.length] = this.ErrorMessage.length + ":" + str;
},
Exec : function(op, reg){
return new RegExp(reg,"g").test(op);
},
compare : function(op1,operator,op2){
switch (operator) {
case "NotEqual":
return (op1 != op2);
case "GreaterThan":
return (op1 > op2);
case "GreaterThanEqual":
return (op1 >= op2);
case "LessThan":
return (op1 < op2);
case "LessThanEqual":
return (op1 <= op2);
default:
return (op1 == op2);
}
},
MustChecked : function(name, min, max){
var groups = document.getElementsByName(name);
var hasChecked = 0;
min = min || 1;
max = max || groups.length;
for(var i=groups.length-1;i>=0;i--)
if(groups[i].checked) hasChecked++;
return min <= hasChecked && hasChecked <= max;
},
DoFilter : function(input, filter){
return new RegExp("^.+\.(?=EXT)(EXT)$".replace(/EXT/g, filter.split(/\s*,\s*/).join("|")), "gi").test(input);
},
IsIdCard : function(number){
var date, Ai;
var verify = "10x98765432";
var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
var area = ['','','','','','','','','','','','北京','天津','河北','山西','內蒙古','','','','','','遼寧','吉林','黑龍江','','','','','','','','上海','江蘇','浙江','安微','福建','江西','山東','','','','河南','湖北','湖南','廣東','廣西','海南','','','','重慶','四川','貴州','雲南','西藏','','','','','','','陝西','甘肅','青海','寧夏','新疆','','','','','','臺灣','','','','','','','','','','香港','澳門','','','','','','','','','國外'];
var re = number.match(/^(\d{2})\d{4}(((\d{2})(\d{2})(\d{2})(\d{3}))|((\d{4})(\d{2})(\d{2})(\d{3}[x\d])))$/i);
if(re == null) return false;
if(re[1] >= area.length || area[re[1]] == "") return false;
if(re[2].length == 12){
Ai = number.substr(0, 17);
date = [re[9], re[10], re[11]].join("-");
}
else{
Ai = number.substr(0, 6) + "19" + number.substr(6);
date = ["19" + re[4], re[5], re[6]].join("-");
}
if(!this.IsDate(date, "ymd")) return false;
var sum = 0;
for(var i = 0;i<=16;i++){
sum += Ai.charAt(i) * Wi[i];
}
Ai += verify.charAt(sum%11);
return (number.length ==15 || number.length == 18 && number == Ai);
},
IsDate : function(op, formatString){
formatString = formatString || "ymd";
var m, year, month, day;
switch(formatString){
case "ymd" :
m = op.match(new RegExp("^((\\d{4})|(\\d{2}))([-./])(\\d{1,2})\\4(\\d{1,2})$"));
if(m == null ) return false;
day = m[6];
month = m[5]*1;
year = (m[2].length == 4) ? m[2] : GetFullYear(parseInt(m[3], 10));
break;
case "dmy" :
m = op.match(new RegExp("^(\\d{1,2})([-./])(\\d{1,2})\\2((\\d{4})|(\\d{2}))$"));
if(m == null ) return false;
day = m[1];
month = m[3]*1;
year = (m[5].length == 4) ? m[5] : GetFullYear(parseInt(m[6], 10));
break;
default :
break;
}
if(!parseInt(month)) return false;
month = month==0 ?12:month;
var date = new Date(year, month-1, day);
return (typeof(date) == "object" && year == date.getFullYear() && month == (date.getMonth()+1) && day == date.getDate());
function GetFullYear(y){return ((y<30 ? "20" : "19") + y)|0;}
}
}
</script>
更新歷史:
1.01
修正對12月份的日期驗證(感謝flylg999)
1.03
修正Range驗證類型時將數字當字符串比較的bug(感謝cncom和xtlhnhbb)
修正日期驗證(感謝Papsam)
增加Username驗證類型
增加對Phone驗證類型時支持分機號
1.04
增加文件格式的過濾,用於上傳時限制上傳的文件格式
1.05
增強對身份證號碼的驗證
[PHP]版
代碼拷貝框
<title>表單驗證類 Validator for PHP β</title>
<style>
body,td{font:normal 12px Verdana;color:#333333}
input,textarea,select,td{font:normal 12px Verdana;color:#333333;border:1px solid #999999;background:#ffffff}
table{border-collapse:collapse;}
td{padding:3px}
input{height:20;}
textarea{width:80%;height:50px;overfmin:auto;}
form{display:inline}
</style>
<table align="center">
<form action="Validator.php" method="post">
<tr>
<td>提示模式:</td><td>
<select name="emode">
<option value="1">警告提示框(客戶端)</option>
<option value="2">提示框加紅色文字提示</option>
<option value="3">附加紅色提示</option>
<option value="4">警告提示框(服務器端)</option>
<option value="5">文字提示(服務器端)</option>
</select></td>
</tr>
<tr>
<td>真實姓名:</td><td><input name="Name"></td>
</tr>
<tr>
<td>英文名:</td><td><input name="Nick"></td>
</tr>
<tr>
<td>主頁:</td><td><input name="Homepage"></td>
</tr>
<tr>
<td>密碼:</td><td><input name="Password"></td>
</tr>
<tr>
<td>重複:</td><td><input name="Repeat"></td>
</tr>
<tr>
<td>信箱:</td><td><input name="Email"></td>
</tr>
<tr>
<td>信箱:</td><td><input name="Email1"></td>
</tr>
<tr>
<td>QQ:</td><td><input name="QQ"></td>
</tr>
<tr>
<td>身份證:</td><td><input name="Card"></td>
</tr>
<tr>
<td>年齡:</td><td><input name="Year"></td>
</tr>
<tr>
<td>年齡1:</td><td><input name="Year1"></td>
</tr>
<tr>
<td>電話:</td><td><input name="Phone"></td>
</tr>
<tr>
<td>手機:</td><td><input name="Mobile"></td>
</tr>
<tr>
<td>生日:</td><td><input name="Birthday"></td>
</tr>
<tr>
<td>郵政編碼:</td><td><input name="Zip"></td>
</tr>
<tr>
<td>郵政編碼:</td><td><input name="Zip1"></td>
</tr>
<tr>
<td>操作系統:</td><td><select name="OS"><option value="">選擇您所用的操作系統</option><option value="Win98">Win98</option><option value="Win2k">Win2k</option><option value="WinXP">WinXP</option></select></td>
</tr>
<tr>
<td>所在省份:</td><td>廣東<input name="Province" value="1" type="radio">陝西<input name="Province" value="2" type="radio">浙江<input name="Province" value="3" type="radio">江西<input name="Province" value="4" type="radio"></td>
</tr>
<tr>
<td>愛好:</td><td>運動<input name="Favorite" value="1" type="checkbox">上網<input name="Favorite" value="2" type="checkbox">聽音樂<input name="Favorite" value="3" type="checkbox">看書<input name="Favorite" value="4" type="checkbox"></td>
</tr>
<td>自我介紹:</td><td><textarea name="Description">中文是一個字</textarea></td>
</tr>
<td>自傳:</td><td><textarea name="History">中文是兩個字節t</textarea></td>
</tr>
<tr>
<td colspan="2"><input name="Submit" type="submit" value="確定提交"></td>
</tr>
</form>
</table>
<script defer>
/*************************************************
Validator for PHP β 客戶端腳本
code by 我佛山人
[email protected]
http://www.cunite.com
*************************************************/
function dispError(items, messages, mode, separator){
var iArray = items.split(separator);
for(var i=iArray.length-1;i>=0;i--)
iArray[i] = getObj(iArray[i]);
messages = ("以下原因導致提交失敗:\t\t\t\t" + separator + messages).split(separator);
switch(mode){
case 2 :
for(i=iArray.length-1;i>=0;i--)
iArray[i].style.color = "red";
case 1 :
alert(messages.join("\n"));
iArray[0].focus();
break;
case 3 :
for(i=iArray.length-1;i>=0;i--){
try{
var span = document.createElement("SPAN");
span.id = "__ErrorMessagePanel";
span.style.color = "red";
iArray[i].parentNode.appendChild(span);
span.innerHTML = messages[i+1].replace(/\d+:/,"*");
}
catch(e){alert(e.description);}
}
iArray[0].focus();
break;
}
}
function getObj(name){
var objs = document.getElementsByName(name);
return objs[objs.length -1];
}
</script>
<?php
class Validator{
/*************************************************
Validator for PHP β 服務器端腳本
code by 我佛山人
[email protected]
http://www.cunite.com
*************************************************/
var $submit;
var $error_item, $error_message, $error_mode, $error_no;
function Validator($submit_name = "Submit", $mode = 5){
$this->submit = $submit_name;
$this->error_mode = $mode;
$this->error_no = 1;
}
function Validate($arr){
if(! isset($_POST[$this->submit])) return false;
$this->error_mode = $_POST["emode"];
echo "<script defer>document.getElementsByName(\"emode\")[0].selectedIndex =" . ($this->error_mode - 1) . "</script>";
if(is_array($arr)){
$len = count($arr);
for($i = 0; $i < $len; $i++){
$this->is_valid($arr[$i]);
}
}
if($this->error_no > 1)
$this->display_error();
}
function is_valid($str){
$str = split(",", $str);
if(count($str) < 3) return false;
$name = trim($str[0]);
$message = trim($str[1]);
$data_type = trim($str[2]);
$value = trim($_POST[$name]);
switch($data_type){
case "compare" :
break;
case "range" :
break;
case "repeat" :
break;
default :
$method = "is_".$data_type;
if(!$this->$method($value))
$this->add_error($name, $message);
break;
}
}
function add_error($name, $message){
$this->error_item .= "," . $name;
$this->error_message .= "," . $this->error_no . ":" . $message;
$this->error_no ++;
}
function display_error(){
$this->error_item = ereg_replace("^,+", "", $this->error_item);
$this->error_message = ereg_replace("^,+", "", $this->error_message);
switch($this->error_mode){
case 4 :
$info = "以下原因導致提交失敗:\t\t\t\t,";
echo "<script>alert(\"".join("\\n", split(",", $info . $this->error_message))."\")</script>";
//print >>>end;
break;
case 5 :
echo "輸入有錯誤:<br /><ul><li>" . ereg_replace( "\b\d+:", "",join("</li><li>", split(",", $this->error_message))) . "</li></ul>";
echo "<br /><a href='javascript:history.back()'>返回</a>";
exit;
break;
default :
echo "<script defer>dispError(\"" . $this->error_item . "\", \"" . $this->error_message . "\", " . $this->error_mode . ", \",\")</script>";
break;
}
}
function is_email($str){
return preg_match("/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/", $str);
}
function is_url($str){
return preg_match("/^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"])*$/", $str);
}
function is_qq($str){
return preg_match("/^[1-9]\d{4,8}$/", $str);
}
function is_zip($str){
return preg_match("/^[1-9]\d{5}$/", $str);
}
function is_idcard($str){
return preg_match("/^\d{15}(\d{2}[A-Za-z0-9])?$/", $str);
}
function is_chinese($str){
return ereg("^[".chr(0xa1)."-".chr(0xff)."]+$",$str);
}
function is_english($str){
return preg_match("/^[A-Za-z]+$/", $str);
}
function is_mobile($str){
return preg_match("/^((\(\d{3}\))|(\d{3}\-))?13\d{9}$/", $str);
}
function is_phone($str){
return preg_match("/^((\(\d{3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}$/", $str);
}
function is_safe($str){
return (preg_match("/^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\'\"]*)|.{0,5})$|\s/", $str) != 0);
}
}
$v = new Validator();
$v->Validate(array("Name,名字只允許中文,chinese", "Nick, 只允許英文暱稱, english", "Homepage, 主頁Url格式不正確, url", "Password, 密碼不符合安全規則, safe","Email,信箱格式錯誤,email", "QQ, QQ號碼不存在, qq","Card, 身份證號碼不正確, idcard","Phone, 電話號碼不存在, phone","Mobile, 手機號碼不存在, mobile","Zip, 郵政編碼不存在, zip"));
?>
[ASP]版代碼拷貝框
<%
Class Validator
'*************************************************
' Validator for ASP beta 2 服務器端腳本
' code by 我佛山人
' [email protected]
' http://www.cunite.com
'*************************************************
Private Re, Dic
Private Separator
Private ErrorItem, ErrorMessage, ErrorMode, ErrorNo
Private FormName, FormIndex, FilePath, GetMethod
Private Sub Class_Initialize()
Set Re = New RegExp
Re.IgnoreCase = True
Re.Global = True
Set Dic = CreateObject("Scripting.Dictionary")
Separator = ","
ErrorItem = ""
ErrorMessage = ""
ErrorMode = 5
ErrorNo = 1
FilePath = Server.MapPath(Request.ServerVariables("Script_Name"))
GetMethod = "FSO"
End Sub
Private Sub Class_Terminate()
Set Re = Nothing
Dic.RemoveAll()
Set Dic = Nothing
End Sub
Public Sub Validate()
IF Request("Submit")="" Then Exit Sub
IF Not IsValidPost() Then Exit Sub
With Dic
.Add "Compare", "Compare( PostValue, operator, toObj)"
.Add "Custom", "Custom( PostValue,regexp )"
.Add "Date", "IsDateFormat( PostValue,format )"
.Add "Limit", "Limit( PostValue,min, max )"
.Add "LimitB", "LimitB( PostValue,min, max )"
.Add "Range", "Range( PostValue,min, max )"
.Add "Repeat", "IsEqual( PostValue, Request(toObj) )"
.Add "Group", "Group( PostValue,min, max )"
.Add "NotEqual", "Op1 <> Op2"
.Add "GreaterThan", "Op1 > Op2"
.Add "GreaterThanEqual", "Op1 >= Op2"
.Add "LessThan", "Op1 < Op2"
.Add "LessThanEqual", "Op1 <= Op2"
.Add "Equal", "Op1 = Op2"
End With
Call MatchCode()
IF ErrorMessage <> "" Then DisplayError
End Sub
Private Sub MatchCode()
Dim bI, bG, bM
Dim Str
Select Case GetMethod
Case "FSO" :
Dim FSO : Set FSO = Server.CreateObject("Scripting.FileSystemObject")
Set TS = FSO.OpenTextFile(FilePath, 1, false)
Str = TS.ReadAll()
TS.Close
Set TS = Nothing
Set FSO = Nothing
Case "XMLHTTP" :
Dim XHttp : Set XHttp = Server.CreateObject("MSXML2.XMLHTTP")
With XHttp
Call .Open("Get", "http://"&Request.ServerVariables("Server_Name")&Request.ServerVariables("Script_Name"), False)
Call .Send()
Str =B2S(.responseBody)
End With
Set XHttp = Nothing
End Select
Dim itemString
With Re
bI = .IgnoreCase
bG = .Global
bM = .MultiLine
.IgnoreCase = True
.Global = True
.Pattern = "[\s\S]*<form [^>]+>([\s\S]+)<\/form>[\s\S]*"
Str = .Replace(Str, "$1")
.Global = True
.MultiLine = True
.Pattern = "<\/?(?!input|textarea|select)[^>]*>"
Str = .Replace(Str, "")
.Pattern = "^.*(<(?=input|textarea|select)[^>]*>).*$"
Str = .Replace(Str, "$1")
.Pattern = "([\r\n]+|^\s*)(?=<)"
Str = .Replace(Str, "")
While Test("dataType=([""\'])([^""\'>]+)\1", Str)
.MultiLine = False
.Pattern = "^([^\n]+)\n([\s\S]*)$"
itemString = .Replace(Str, "$1")
Str = .Replace(Str, "$2")
.Pattern = "(name|dataType|to1|min|max|msg|require|regexp|format)=([""\'])([^""\'>]+)\2"
Dim Matches : Set Matches = .Execute(itemString)
Dim Match, RetStr : RetStr = ""
For Each Match in Matches
RetStr = RetStr & Match.Value & " : "
Next
Call IsValid(Replace(Replace(Replace(RetStr, " : $", ""), "to=", "toObj="), """Require""", """NotEmpty"""))
Wend
.IgnoreCase = bI
.Global = bG
.MultiLine = bM
End With
End Sub
Private Sub IsValid(ByVal Str)
Dim name, msg, dataType, toObj, min, max, require, regexp, format
min = 1 : max = 100 : require = "true" : format = "YMD"
Execute Str
Dim PostValue : PostValue = Request(name)
Dim Fun
IF require = "false" AND PostValue = "" Then Exit Sub
IF Dic.Exists(dataType) Then
Fun = Dic.Item(dataType)
Else Fun = "Is" & dataType &"( PostValue )"
End IF
IF Not Eval(Fun) Then Call AddError(name,msg)
End Sub
Private Sub DisplayError()
ErrorItem = Replace(ErrorItem, "^(" & Separator & ")", "")
ErrorMessage = Replace(ErrorMessage, "^(" & Separator & ")", "")
Select Case ErrorMode
Case 4
ErrorMessage = Join(Split(ErrorMessage, Separator), "</li><li>")
Response.Clear
Response.Write "<div style=""padding-left:100px;font:bold 12px Tahoma"">輸入有錯誤:<br><ul><li>" & Replace(ErrorMessage, "\b\d+:", "") & "</li></ul>"
Response.Write "<br><a href='javascript:history.back()'>返回重填</a></div>"
Response.End
Case Else
Response.Write("<script defer>dispError(""" & ErrorItem & """, """ & ErrorMessage & """, " & ErrorMode & ", """ & Separator & """)</script>")
End Select
End Sub
Public Function IsEmail(ByVal Str)
IsEmail = Test("^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", Str)
End Function
Public Function IsUrl(ByVal Str)
IsUrl = Test("^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>""])*$", Str)
End Function
Public Function IsNum(ByVal Str)
IsNum= Test("^\d+$", Str)
End Function
Public Function IsQQ(ByVal Str)
IsQQ = Test("^[1-9]\d{4,8}$", Str)
End Function
Public Function IsZip(ByVal Str)
IsZip = Test("^[1-9]\d{5}$", Str)
End Function
Public Function IsIdCard(ByVal Str)
IsIdCard = Test("^\d{15}(\d{2}[A-Za-z0-9])?$", Str)
End Function
Public Function IsChinese(ByVal Str)
IsChinese = Test("^[\u0391-\uFFE5]+$", Str)
End Function
Public Function IsEnglish(ByVal Str)
IsEnglish = Test("^[A-Za-z]+$", Str)
End Function
Public Function IsMobile(ByVal Str)
IsMobile = Test("^((\(\d{3}\))|(\d{3}\-))?13\d{9}$", Str)
End Function
Public Function IsPhone(ByVal Str)
IsPhone = Test("^((\(\d{3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}$", Str)
End Function
Public Function IsSafe(ByVal Str)
IsSafe = (Test("^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\'\""]*)|.{0,5})$|\s", Str) = False)
End Function
Public Function IsNotEmpty(ByVal Str)
IsNotEmpty = LenB(Str) > 0
End Function
Public Function IsDateFormat(ByVal Str, ByVal Format)
IF Not IsDate(Str) Then
IsDateFormat = False
Exit Function
End IF
IF Format = "YMD" Then
IsDateFormat = Test("^((\d{4})|(\d{2}))([-./])(\d{1,2})\4(\d{1,2})$", Str)
Else
IsDateFormat = Test("^(\d{1,2})([-./])(\d{1,2})\\2((\d{4})|(\d{2}))$", Str)
End IF
End Function
Public Function IsEqual(ByVal Src, ByVal Tar)
IsEqual = (Src = Tar)
End Function
Public Function Compare(ByVal Op1, ByVal Operator, ByVal Op2)
Compare = False
IF Dic.Exists(Operator) Then
Compare = Eval(Dic.Item(Operator))
Elseif IsNotEmpty(Op1) Then
Compare = Eval(Op1 & Operator & Op2 )
End IF
End Function
Public Function Range(ByVal Src, ByVal Min, ByVal Max)
Min = CInt(Min) : Max = CInt(Max)
Range = (Min < Src And Src < Max)
End Function
Public Function Group(ByVal Src, ByVal Min, ByVal Max)
Min = CInt(Min) : Max = CInt(Max)
Dim Num : Num = UBound(Split(Src, ",")) + 1
Group = Range(Num, Min - 1, Max + 1)
End Function
Public Function Custom(ByVal Str, ByVal Reg)
Custom = Test(Reg, Str)
End Function
Public Function Limit(ByVal Str, ByVal Min, ByVal Max)
Min = CInt(Min) : Max = CInt(Max)
Dim L : L = Len(Str)
Limit = (Min <= L And L <= Max)
End Function
Public Function LimitB(ByVal Str, ByVal Min, ByVal Max)
Min = CInt(Min) : Max = CInt(Max)
Dim L : L =bLen(Str)
LimitB = (Min <= L And L <= Max)
End Function
Private Function Test(ByVal Pattern, ByVal Str)
Re.Pattern = Pattern
Test = Re.Test(Str)
End Function
Public Function bLen(ByVal Str)
bLen = Len(Replace(Str, "[^\x00-\xFF]", ".."))
End Function
Private Function Replace(ByVal Str, ByVal Pattern, ByVal ReStr)
Re.Pattern = Pattern
Replace = Re.Replace(Str, ReStr)
End Function
Private Function B2S(ByVal iStr)
Dim reVal : reVal= ""
Dim i, Code, nCode
For i = 1 to LenB(iStr)
Code = AscB(MidB(iStr, i, 1))
IF Code < &h80 Then
reVal = reVal & Chr(Code)
Else
nCode = AscB(MidB(iStr, i+1, 1))
reVal = reVal & Chr(CLng(Code) * &h100 + CInt(nCode))
i = i + 1
End IF
Next
B2S = reVal
End Function
Private Sub AddError(ByVal Name, ByVal Message)
ErrorItem = ErrorItem & Separator & Name
ErrorMessage = ErrorMessage & Separator & ErrorNo & ":" & Message
ErrorNo = ErrorNo + 1
End Sub
Public Function IsValidPost()
Dim Url1 : Url1 = Cstr(Request.ServerVariables("HTTP_REFERER"))
Dim Url2 : Url2 = Cstr(Request.ServerVariables("SERVER_NAME"))
IsValidPost = (Mid(Url1, 8, Len(Url2)) = Url2)
End Function
Public Property Let Mode(ByVal Val)
ErrorMode = CInt(Val)
End Property
Public Property Let Form(ByVal Val)
IF IsNumeric(Val) Then
FormIndex = Val
Else
FormName = Val
End IF
End Property
Public Property Let Path(ByVal Val)
IF Test("^[A-Za-z]:\\\w+$", Val) Then
FilePath = Val
Else
FilePath = Server.MapPath(Val)
End IF
End Property
Public Property Let Method(ByVal Val)
GetMethod = Val
End Property
End Class
%>
<title>表單驗證類 Validator v1.0</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
body,td{font:normal 12px Verdana;color:#333333}
input,textarea,select,td{font:normal 12px Verdana;color:#333333;border:1px solid #999999;background:#ffffff}
table{border-collapse:collapse;}
td{padding:3px}
input{height:20;}
textarea{width:80%;height:50px;overfmin:auto;}
form{display:inline}
</style>
<script>
/*************************************************
Validator for ASP beta 2 客戶端腳本
code by 我佛山人
[email protected]
http://www.cunite.com
*************************************************/
function dispError(items, messages, mode, separator){
var iArray = items.split(separator);
for(var i=iArray.length-1;i>=0;i--)
iArray[i] = getObj(iArray[i]);
messages = ("以下原因導致提交失敗:\t\t\t\t" + separator + messages).split(separator);
switch(mode){
case 2 :
for(i=iArray.length-1;i>=0;i--)
iArray[i].style.color = "red";
case 1 :
alert(messages.join("\n"));
iArray[0].focus();
break;
case 3 :
for(i=iArray.length-1;i>=0;i--){
try{
var span = document.createElement("SPAN");
span.id = "__ErrorMessagePanel";
span.style.color = "red";
iArray[i].parentNode.appendChild(span);
span.innerHTML = messages[i+1].replace(/\d+:/,"*");
}
catch(e){alert(e.description);}
}
iArray[0].focus();
break;
}
}
function getObj(name){
var objs = document.getElementsByName(name);
return objs[objs.length -1];
}
</script>
<form name="theForm" id="demo" action="" method="post" onSubmit="return true">
<table align="center">
<tr>
<td>真實姓名:</td><td><input name="Name" dataType="Chinese" msg="真實姓名只允許中文"></td>
</tr>
<tr>
<td>英文名:</td><td><input name="Nick" dataType="English" require="false" msg="英文名只允許英文字母"></td>
</tr>
<tr>
<td>主頁:</td><td><input name="Homepage" require="false" dataType="Url" msg="非法的Url"></td>
</tr>
<tr>
<td>密碼:</td><td><input name="Password" dataType="Safe" msg="密碼不符合安全規則" type="password"></td>
</tr>
<tr>
<td>重複:</td><td><input name="Repeat" dataType="Repeat" to="Password" msg="兩次輸入的密碼不一致" type="password"></td>
</tr>
<tr>
<td>信箱:</td><td><input name="Email" dataType="Email" msg="信箱格式不正確"></td>
</tr>
<tr>
<td>信箱:</td><td><input name="Email1" dataType="Repeat" to="Email" msg="兩次輸入的信箱不一致"></td>
</tr>
<tr>
<td>QQ:</td><td><input name="QQ" require="false" dataType="QQ" msg="QQ號碼不存在"></td>
</tr>
<tr>
<td>身份證:</td><td><input name="Card" dataType="IdCard" msg="身份證號碼不正確"></td>
</tr>
<tr>
<td>年齡:</td><td><input name="Year" dataType="Range" msg="年齡必須在18~28之間" min="18" max="28"></td>
</tr>
<tr>
<td>年齡1:</td><td><input name="Year1" require="false" dataType="Compare" msg="年齡必須在18以上" to1="18" operator="GreaterThanEqual"></td>
</tr>
<tr>
<td>電話:</td><td><input name="Phone" require="false" dataType="Phone" msg="電話號碼不正確"></td>
</tr>
<tr>
<td>手機:</td><td><input name="Mobile" require="false" dataType="Mobile" msg="手機號碼不正確"></td>
</tr>
<tr>
<td>生日:</td><td><input name="Birthday" dataType="Date" format="YMD" msg="生日日期不存在"></td>
</tr>
<tr>
<td>郵政編碼:</td><td><input name="Zip" dataType="Custom" regexp="^[1-9]\d{5}$" msg="郵政編碼不存在"></td>
</tr>
<tr>
<td>郵政編碼:</td><td><input name="Zip1" dataType="Zip" msg="郵政編碼不存在"></td>
</tr>
<tr>
<td>操作系統:</td><td><select name="OS" dataType="Require" msg="未選擇所用操作系統" ><option value="">選擇您所用的操作系統</option><option value="Win98">Win98</option><option value="Win2k">Win2k</option><option value="WinXP">WinXP</option></select></td>
</tr>
<tr>
<td>所在省份:</td><td>廣東<input name="Province" value="1" type="radio">陝西<input name="Province" value="2" type="radio">浙江<input name="Province" value="3" type="radio">江西<input name="Province" value="4" type="radio" dataType="Group" msg="必須選定一個省份"></td>
</tr>
<tr>
<td>愛好:</td><td>運動<input name="Favorite" value="1" type="checkbox">上網<input name="Favorite" value="2" type="checkbox">聽音樂<input name="Favorite" value="3" type="checkbox">看書<input name="Favorite" value="4" type="checkbox" dataType="Group" min="2" max="3"
msg="必須選擇2~3種愛好"></td>
</tr>
<tr>
<td>自我介紹:</td><td><textarea name="Description" dataType="Limit" max="10" msg="自我介紹內容必須在10個字之內">中文是一個字</textarea></td>
</tr>
<tr>
<td>自傳:</td><td><textarea name="History" dataType="LimitB" min="3" max="10" msg="自傳內容必須在[3~10]個字節之內">中文是兩個字節t</textarea></td>
</tr>
<tr>
<td colspan="2"><input name="Submit" type="submit" value="確定提交"></td>
</tr>
</table>
</form>
<%
Dim V : Set V = New Validator
V.Mode = 3
V.Method = "XMLHTTP"
V.Validate()
Set V = Nothing
%>
</body>
</html>