使用go搭建一个简单的web服务器(3)验证表单的输入
1.登陆页面
# login.html
<html> <head> <title>login</title> </head> <body> <form action="http://127.0.0.1:9090/login" method="post"> 用户名:<input type="text" name="username"> 密码:<input type="password" name="password"> <input type="submit" value="登陆"> </form> </body> </html>
2.注册页面
# register.html
<html> <head> <title>register</title> </head> <body> <form action="http://127.0.0.1:9090/register" method="post"> 用户名:<input type="text" name="username"> 密码:<input type="password" name="password"> 年龄:<input type="text" name="age"> 电子邮箱:<input type="text" name="email"> 手机号码:<input type="text" name="mobile"> <select name="fruit"> <option value="apple">apple</option> <option value="pear">pear</option> <option value="banane">banane</option> </select> <input type="radio" name="gender" value="1">男 <input type="radio" name="gender" value="2">女 <input type="checkbox" name="interest" value="football">足球 <input type="checkbox" name="interest" value="basketball">篮球 <input type="checkbox" name="interest" value="tennis">网球 身份证号:<input type="text" name="usercard"> <input type="submit" value="注册"> </form> </body> </html>
3.后端处理逻辑
package main import ( "fmt" "html/template" "log" "net/http" "regexp" "strconv" "strings" ) func In_slice(val string, slice []string) bool { for _, v := range slice { if v == val { return true } } return false } func Slice_diff(slice1, slice2 []string) (diffslice []string) { for _, v := range slice1 { if !In_slice(v, slice2) { diffslice = append(diffslice, v) } } return } func sayhelloname(w http.ResponseWriter, r *http.Request) { r.ParseForm() //解析参数,默认是不会解析的。 fmt.Println(r.Form) fmt.Println("path:", r.URL.Path) fmt.Println("scheme:", r.URL.Scheme) fmt.Println(r.Form["url_long"]) for k, v := range r.Form { fmt.Println("key:", k) fmt.Println("value:", strings.Join(v, ",")) } fmt.Fprintf(w, "hello, welcome you!") //这个字符串写入到w中,用于返回给客户端。 } func login(w http.ResponseWriter, r *http.Request) { fmt.Println("method: ", r.Method) if r.Method == "GET" { t, _ := template.ParseFiles("login.html") t.Execute(w, nil) } else { r.ParseForm() fmt.Println("username: ", r.Form["username"]) fmt.Println("password:", r.Form["password"]) } } func register(w http.ResponseWriter, r *http.Request) { fmt.Println("method:", r.Method) if r.Method == "GET" { t, _ := template.ParseFiles("register.html") t.Execute(w, nil) } else { r.ParseForm() //r.Form对不通类型的表单元素的留空的处理: //对于空文本框、空文本区域及文件上传,元素的值为空值 //如果是未选中的复选框和单选按钮,不会在r.Form中产生相应的条目,通过r.Form获取不存在的元素会报错。 //r.Form.get()可以返回不存在元素的值为空值,不会报错,但只能获取单个的值,如果是map的值,必须通过r.Form来获取。 if len(r.Form["username"][0]) == 0 { //用户名为空的处理 } //期望用户名为中文。 if m, _ := regexp.MatchString("^[\\x{4e00}-\\x{9fa5}]+$", r.Form.Get("username")); !m { //username不是中文的或不完全是中文的 } //期望用户名是英文。 if m, _ := regexp.MatchString("^[a-zA-Z]+$", r.Form.Get("username")); !m { //username不是英文的或不完全是英文的 } //strconv包提供了字符串与简单数据类型之间的类型转换功能。可以将简单类型转换为字符串,也可以将字符串转换为其它简单类型 //这个包里提供的函数有一个是,字符串转int:Atoi() getint, err := strconv.Atoi(r.Form.Get("age")) if err != nil { //转化出错了,age可能不是int类型。 } if getint <= 0 && getint > 100 { //年龄不在正常范围内 } //使用正则表达式来判断,regexp.MatchString函数用于将字符串与正则表达式进行匹配,如果能匹配成功,返回true if m, _ := regexp.MatchString("^[0-9]+$", r.Form.Get("age")); !m { //age不是int类型 } //验证电子邮件是否满足格式的要求 if m, _ := regexp.MatchString(`^([\w\.\_]{2,10})@(\w{1,}).([a-z]{2,4})$`, r.Form.Get("email")); !m { //不满足要求 } //验证手机号是否满足格式要求 if m, _ := regexp.MatchString(`^(1[3|4|5|8][0-9]\d{4,8})$`, r.Form.Get("mobile")); !m { //不满足要求 } //验证下拉菜单 option_slice := []string{"apple", "pear", "banane"} for _, v := range option_slice { if v == r.Form.Get("fruit") { //下拉选项正确的情况 } //下拉选项不正确的情况 } //验证单选按钮 radio_slice := []int{1, 2} for _, v := range radio_slice { if strconv.Itoa(v) == r.Form.Get("gender") { //单选按钮正确的情况 } //单选按钮错误的情况 } //验证复选框 checkbox_slice := []string{"football", "basketball", "tennis"} a := Slice_diff(r.Form["interest"], checkbox_slice) if a == nil { //复选框按钮正确的情况 } else { //复选框按钮错误的情况 } //验证15位身份证,15位的是全部数据 if m, _ := regexp.MatchString(`^(\d{15})`, r.Form.Get("usercard")); !m { //不满足的情况 } //验证18位身份证,18位前17位为数字,最后一位是校验位,可能为数字或者字符X if m, _ := regexp.MatchString(`^(\d{17}([0-9]|X))$`, r.Form.Get("usercard")); !m { //不满足的情况 } } } func main() { http.HandleFunc("/", sayhelloname) //设置访问的路由 http.HandleFunc("/login", login) //设置访问的路由 http.HandleFunc("/register", register) //设置访问的路由 err := http.ListenAndServe(":9090", nil) //设置监听的端口 if err != nil { log.Fatal("ListenAndServe: ", err) } }
人生短,迷茫路一程又一程。
脚步重,雨雪天踟蹰也踟蹰。
滴水聚,久无成效伊人不见。
该如何,敲击敲击昼夜不停。