前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go HTTP 编程 | 03 - 表单的输入与验证

Go HTTP 编程 | 03 - 表单的输入与验证

作者头像
RiemannHypothesis
发布2022-11-25 11:33:44
1.3K0
发布2022-11-25 11:33:44
举报
文章被收录于专栏:ElixirElixir

一、表单的输入

表单是 Web 应用中非常中重要的组成部分,通过表单可以方法的让客户端和服务器进行数据的交互。Go 中对于 form 的处理非常方便,在 Request 中有专门的 form 处理方法。

以登录表单为例,新建一个登录表达 login.gtpl,表单内容如下:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Login Form</title>
</head>
<body>
<form action="http://localhost:9000/login" method="post">
    USERNAME:<input type="text" name="username"> <br>
    PASSWORD:<input type="password" name="password"> <br>
    <input type="submit" value="Sing In">
</form>
</body>
</html>

上述表单收集的信息将会递交到服务器的 /login,当用户输出信息并点击登录的时候,会跳转到服务器的路由 login 里面,所以服务器首先要判断请求时 POST 还是 GET

http 包中有一个简单的方法可以获取请求方式 r.Method 方法,main.go 文件的代码如下:

代码语言:javascript
复制
import (
   "fmt"
   "html/template"
   "log"
   "net/http"
   "strings"
)

//noinspection ALL
func main(){
   http.HandleFunc("/login", login)

   err := http.ListenAndServe(":9000", nil)

   if err != nil {
      log.Fatal("ListenAndServe: ", err)
   }
}


func login(w http.ResponseWriter, r *http.Request){
   fmt.Println("method", r.Method) // 获取请求的方式

   // GET 请求,跳转至登录界面
   if r.Method == "GET" {
      t, _ := template.ParseFiles("form/login.gtpl")
      t.Execute(w, nil)
   } else {
      // 请求的是登录数据,执行登录逻辑
      r.ParseForm()
      fmt.Println("Form Data:", r.Form)
      fmt.Println("username: ", r.Form["username"])
      fmt.Println("password: ", r.Form["password"])
   }
}

上述代码中的 login 方法通过判断语句判断请求方式,如果是 GET 请求则跳转到 login 界面,注意这里填写 login.gtpl 文件的位置一定要准确,否则会报错。

如果不是 GET 请求则会处理提交的数据,其中 r.ParseForm() 会解析 URL,针对 POST 请求则会解析请求体,若没有这一行代码是无法获取的 POST 请求提交的参数的,最后会将提交的数据输出到控制台。

接着就是 main 函数中的路由和端口配置。执行 main 函数启动 Web 服务,在浏览器中输入 localhost:9000/login,浏览器显示如下页面:

image.png
image.png

当是 GET 请求时显示登录页面,输入用户名和密码,点击提交;此时是 POST 请求,则会执行 esle 代码块,即将提交的信息输出到控制台:

image.png
image.png

二、表单的验证

在获取到了用户提交的数据之后,存储到数据库之前,需要对用户提交的数据进行校验,校验可以在前端通过 JavaScript 实现,也可以在服务端进行校验。

必填字段

针对表单中的必填字段,可以通过获取提交的数据的长度来判断提交的数据是否为空:

代码语言:javascript
复制
if len(r.Form["username"][0]) == 0 {
    // 字符串为空的处理
}

r.Form 对不同类型的表单元素的留空有不同的处理,对于空文本框、空文本区域以及文件上传,元素的值为空值,而如果是未选中的复选框和单选按钮,则根本不会在 r.Form 中产生相应的条目,在实际获取程序值的时候需要通过 r.Form.Get() 来获取,若字段不存在,则获取的是空值,但是通过这种方式只能获取单个的值,如果是 map 还需要通过 r.Form["username"][0] 这种方式获取。

数字

如果要确保单选框中的输入只能是数字类型,比如获取用户的年龄,可以先转换成 int 类型,然后在处理:

代码语言:javascript
复制
age, err := strconv.Atoi(r.Form.Get("age"))

if err != nil {
    // 转换为 int 类型出错,说明用户的输入不是数字
}

// 用户输入的数字转换成功,进行下一步操作
if age > 100 {
    // 年龄超过指定范围
}

还可以通过正则表达式的方式来获取:

代码语言:javascript
复制
if m, _ := regexp.MatchString("^[0-9]+$", r.Form.Get("age")); !m {
    return false
}

但是正则表达式的速度相对来说会比较慢。

中文和英文

如果想要获取表单中的中文字符,并确保获取的是正确的中文字符,需要进行验证,而不是随便输入,中文只有通过正则来验证:

代码语言:javascript
复制
if m, _ := regexp.MatchString("^[\\x{4e00}-\\x{9fa5}]+$", r.Form.Get("chineseName")); !m {
    return false
}

如果要获取表单中的英文值,也可以通过正则表达式:

代码语言:javascript
复制
if m, _ := regexp.MatchString("^[a-zA-Z]+$", r.Form.Get("firstName")); !m {
    return false
}

Email, 电话号码和电话号码

验证用户输入的 Email 是否正确,可以通过以下方式验证:

代码语言:javascript
复制
if m, _ := regexp.MatchString(`^([\w\.\_]{2,10})@(\w{1,}).([a-z]{2,4})$`,

r.Form.Get("email")); !m {
    fmt.Println("no")
}else{
    fmt.Println("yes")
}

手机号码可以通过如下方式验证:

代码语言:javascript
复制
if m, _ := regexp.MatchString(`^(1[3|4|5|8][0-9]\d{4,8})$`, r.Form.Get("mobile")); !
m {
    return false
}

对身份证号码,可以通过如下方式验证:

代码语言:javascript
复制
//验证 15 位身份证,15 位的是全部数字

if m, _ := regexp.MatchString(`^(\d{15})$`, r.Form.Get("usercard")); !m {
    return false
}

//验证 18 位身份证,18 位前 17 位为数字,最后一位是校验位,可能为数字或字符 X。

if m, _ := regexp.MatchString(`^(\d{17})([0-9]|X)$`, r.Form.Get("usercard")); !m {
    return false
}

日期与时间

想要判断用户输入的时间是否正确,可以使用 Go 的 time 包,可以将用户的输入转换成相应的时间,然后进行逻辑判断:

代码语言:javascript
复制
t := time.Date(2022, time.November, 10, 23, 0, 0, 0, time.UTC)
fmt.Printf(t.Local())

转换成 Go 的时间就可以进行更多的操作了

下拉菜单,单选按钮和复选框

想要判断下拉菜单中是否有条目被选中,比如 select 是这样的:

代码语言:javascript
复制
<select name="fruit">
    <option value="apple">apple</option>
    <option value="pear">pear</option>
    <option value="banane">banane</option>
</select>

如何判断用户提交的值是 option 其中的一个呢?

代码语言:javascript
复制
slice := []string{"apple", "pear", "banane"}

for _, v := range slice {
    if v == r.Form.Get("fruit") {
           return true
    }
}
return false

针对单选框判断发送的值为预设的值可以使用如下方式:

代码语言:javascript
复制
<input type="radio" name="gender" value="1">男
<input type="radio" name="gender" value="2">女

也是通过遍历的方式判断

代码语言:javascript
复制
slice:=[]int{1,2}

for _, v := range slice {
    if v == r.Form.Get("gender") {
        return true
    }
}

return false

针对复选框的判断有一点不一样,因为复选框接收到的是一个 Slice

代码语言:javascript
复制
<input type="checkbox" name="interest" value="football">足球
<input type="checkbox" name="interest" value="basketball">篮球
<input type="checkbox" name="interest" value="tennis">网球
代码语言:javascript
复制
slice:=[]string{"football","basketball","tennis"}

a:=Slice_diff(r.Form["interest"],slice)
    if a == nil{
        return true
    }
return false
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-11-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、表单的输入
  • 二、表单的验证
    • 必填字段
      • 数字
        • 中文和英文
          • Email, 电话号码和电话号码
            • 日期与时间
              • 下拉菜单,单选按钮和复选框
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档