開發(fā)Web的一個(gè)原則就是,不能信任用戶輸入的任何信息,所以驗(yàn)證和過濾用戶的輸入信息就變得非常重要。為了編寫出安全可靠的Web程序,驗(yàn)證表單輸入的意義重大。
1、必填字段
你想要確保從一個(gè)表單元素中得到一個(gè)值,Go有一個(gè)內(nèi)置函數(shù)len可以獲取字符串的長(zhǎng)度,這樣我們就可以通過len來獲取數(shù)據(jù)的長(zhǎng)度,例如:
if len(r.Form["username"][0]) == 0 {
? ? // 為空的處理
}
r.Form對(duì)不同類型的表單元素的留空有不同的處理:
1)對(duì)于空文本框、空文本區(qū)域以及文件上傳,元素的值為空值;
2)對(duì)于未選中的復(fù)選框和單選按鈕,需要通過r.Form.Get()來獲取值,因?yàn)槿绻侄尾淮嬖?,通過該方式獲取的是空值,但是通過r.Form.Get()只能獲取單個(gè)的值。
2、數(shù)字
如果想要確保一個(gè)表單輸入框中獲取的只能是數(shù)字,例如,你想通過表單獲取某個(gè)人的具體年齡是50歲還是10歲,而不是像“一把年紀(jì)了”或“年輕著呢”這種描述。
如果我們是判斷正整數(shù),那么我們先轉(zhuǎn)化成int類型,然后進(jìn)行處理:
age, err := strconv.Atoi(r.Form.Get("age"))
if err != nil {
? ? // 數(shù)字轉(zhuǎn)換出錯(cuò)了,那么可能不是數(shù)字
}
if age > 100 {
? ? // 年齡太大,義務(wù)異常邏輯處理
}
正則匹配方式:
import "regexp"
if age, _ := regexp.MatchString("^[0-9]+$", r.Form.Get("age")); !age {
? ? return false
}
Go實(shí)現(xiàn)的正則是RE2,所有的字符都是UTF-8編碼的。
3、中文
為了保證獲取的是正確的中文,我們目前有兩種驗(yàn)證方式:可以使用 unicode 包提供的 func Is(rangeTab *RangeTable, r rune)bool 來驗(yàn)證,也可以使用正則方式來驗(yàn)證。
if m, _ := regexp.MatchString("^\\p{Han}+$", r.Form.Get("username")); !m {
????return false
}
4、英文
獲取一個(gè)英文值,通過正則驗(yàn)證數(shù)據(jù):
if m, _ := regexp.MatchString("^[a-zA-Z]+$", r.Form.Get("username")); !m {
????return false
}
5、電子郵件地址
驗(yàn)證Email地址是否正確:
if m, _ := regexp.MatchString(`^([\w\.\_]{2,10})@(\w{1,}).([a-z]{2,4})$`, r.Form.Get("username")); !m {
????return false
}
6、手機(jī)號(hào)碼
if m, _ := regexp.MatchString(`^(1[3|4|5|8][0-9]\d{4,8})$`, r.Form.Get("username")); !m {
????return false
}
7、下拉菜單
判斷表單里面生成的select下拉菜單中是否有被選中的元素:
fruit := []string{"apple", "pear", "banana"}
v := r.Form.Get("fruit")
for _, item := range fruit {
????if item == v {
????????return true
????}
}
return false
8、單選按鈕
判斷radio按鈕是否有一個(gè)被選中了:
gender := []string{"1", "2"}
v := r.Form.Get("gender")
for _, item := range gender {
????if item == v {
????????return true
????}
}
return false
9、復(fù)選框
對(duì)于復(fù)選框checkbox的驗(yàn)證,因?yàn)槲覀兘邮盏降臄?shù)據(jù)是一個(gè)slice:
# go get github.com/astaxie/beeku
import (_ "github.com/astaxie/beeku")
interest := []string{"football", "basketball", "tennis"}
//?Slick_diff在庫github.com/astaxie/beeku
diff := Slice_diff(r.Form["interest"], interest) ? ?if diff == nil {
????return true
}
return false
10、身份證號(hào)碼
// 驗(yàn)證15位身份證,全部是數(shù)字
if m, _ := regexp.MatchString(`^(\d{15})$`, r.Form.Get("userid")); !m {
????return
}
// 驗(yàn)證18位身份證,最后一位是校驗(yàn)位,可能為數(shù)字或字符X
if m, _ := regexp.MatchString(`^(\d{17})([0-9]|X)$`, r.Form.Get("userid")); !m {
????return
}