表单:(Form)是客户端提交的数据,如我们在搜索时在搜索引擎中输入的数据,再比如我们在登录时向服务器提交的用户名和密码,都属于表单
对于表单的处理,首先在处理器函数中,重要的是要解析表单数据(r.ParseForm() )
1.处理表单的输入
login.html
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/say" method="post">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" value="登录">
</form>
</body>
</html>
main.go
package main
import (
"fmt"
"html/template"
"net/http"
)
//写一个路由函数(处理器函数),传入两个参数,一是向响应体中写的操作变量,一个是http的请求
func sayName(w http.ResponseWriter,r *http.Request){
//解析html文件
t,_:=template.ParseFiles("G:\\goproject\\src\\goweb\\07formProcessing\\demo01\\main\\login.html")
//执行解析后的html文件
t.Execute(w,nil)
r.ParseForm() //解析请求中url中携带的参数,如果是post方法则解析请求包中的主体
//如果此处不进行解析表单,下面将无法获取表单中的数据
fmt.Println(r.Method)
if r.Method=="POST"{
fmt.Println(r.Form) //输出表单中的数据
fmt.Println("path",r.URL.Path)//表单中的路径
fmt.Println("username:",r.Form["username"])
fmt.Println("password:",r.Form["password"])
}
}
func main(){
http.HandleFunc("/say",sayName)
err:=http.ListenAndServe(":9090",nil)
if err!=nil{
fmt.Println("err=",err)
}
}
第一次在浏览器中输入127.0.0.1:9090/say后显示
在服务器中显示
意味着我们第一次是用GET方法向服务器发送请求,
接下来,输入用户名和密码,点击登录
在服务器的控制台显示:
因此第二次我们点击登录时post方法,并且,服务器也接收到客户端传递的表单
2.验证表单的输入
比如客户端传递给服务器一个表单,我们向=想知道这个表单是时间类型的还是电子邮件地址类型的,或者是身份证号类型的,这个时候服务器就要使用正则匹配机制进行验证(当然前端也有一些方法进行验证,我们这里只说明后端如何验证)
验证表单输入的类型有
具体如何实现,网上有很多方法,
golang包中regexp包实现正则表达式搜索
如regexp包中的MatchString方法
3.防止多次递交表单
由于个人原因或者电脑原因,有时候会多次递交重复的表单
解决办法:在前端的html页面中,增加一个token(隐藏字段)
token的实现,可以通过时间戳(time.Now().Unix())来多个一个int值(该值唯一),然后使用密码学中的hsah函数(md5)对该值进行处理
test.html
<html>
<head>
<title>上传文件</title>
</head>
<body>
<form enctype="multipart/form-data" action="/upload" method="post">
<input type="file" name="uploadfile" />
<input type="hidden" name="token" value="{{.}}"/>
<input type="submit" value="upload" />
</form>
</body>
</html>
main.go
package main
import (
"fmt"
"html/template"
"net/http"
"os"
)
func upload(w http.ResponseWriter,r *http.Request){
fmt.Println("method:",r.Method)
t,_:=template.ParseFiles("G:\\goproject\\src\\goweb\\07formProcessing\\demo04\\main\\upload.html")
t.Execute(w,nil)
r.ParseMultipartForm(32<<20)
file,handler,err:=r.FormFile("uploadfile")
if err!=nil{
fmt.Println(err)
return
}
defer file.Close()
//向w中写入请求的文件部分
fmt.Fprintf(w,"%v",handler.Header)
f,err:=os.OpenFile("./test/"+handler.Filename,os.O_WRONLY|os.O_CREATE,0666)
if err!=nil{
fmt.Println(err)
return
}
defer f.Close()
//io.Copy(f,file)
}
func main(){
http.HandleFunc("/",upload)
err:=http.ListenAndServe(":9090",nil)
if err!=nil{
fmt.Println(err)
}
}
我们在浏览器中输入127.0.0.1:9090/ 显示页面
点开该网页的源代码
当我们再第二次刷新页面之后
token的值发生变化,同时再服务器的控制台我们也可以得到token的值
服务器可以根据token 的值来判断该表单是否是多次重复提交