引言
再web开发中(B/S架构),浏览器会和服务器进行通信,通信的方式就是表单。
他们之间的基本逻辑为,在服务端写好HTML文件,当浏览器请求界面时,服务器将HTML文件发给浏览器,然后用户在浏览器输入信息,移交之后,将收到的信息一表单发给服务器进行逻辑处理。
get和post
浏览器向服务器请求数据一般有两种方式:get和post。
两者的异同:
相同点:
都是向服务器发送请求。
不同点:
浏览器在向服务器发请求时会携带一些信息。get会将请求信息写在url中,而post会将请求信息写在请求体body中(get没有请求体)。
上图为get的请求方式。
get和post的使用场景:
- get:请求界面,搜索引擎检索
- post: 提交form表单时。
go处理表单的输入
源码:
先来看一个表单递交的例子,我们有如下的表单内容,命名成文件 login.gtpl(放入当前新建
项目的目录里面) 。
<html>
<head>
<title></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>
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"strings"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //解析 url 传递的参数,对于 POST 则解析响应包的主体(request body)
//注意:如果没有调用 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("val:", strings.Join(v, ""))
}
fmt.Fprintf(w, "Hello astaxie!") //这个写入到 w 的是输出到客户端的
}
func login(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method) //获取请求的方法
if r.Method == "GET" {
t, _ := template.ParseFiles("login.gtpl") //解析模板
t.Execute(w, nil) //渲染模板,并发送
} else {
//请求的是登陆数据,那么执行登陆的逻辑判断
//解析表单
r.ParseForm()
fmt.Println("username:", r.Form["username"])
fmt.Println("password:", r.Form["password"])
}
}
func main() {
http.HandleFunc("/", sayhelloName) //设置访问的路由
http.HandleFunc("/login", login) //设置访问的路由
err := http.ListenAndServe(":9090", nil) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
调试结果:
- 在浏览器输入
127.o.0.1:9090/login ,得到下列界面:
- 输入数据点击登陆后,在后台接受的数据为:
细节分析:
当浏览器端输入信息点击登陆后,输入的信息会被整理成key-value的形式,并包装成request包发给服务器,
服务端接收到后的请求r的数据结构是一个结构体,输入的内容放在了r.Form字段中,这是一个 slice,里面存储了多 个值。注意在读取这些值时要先进行解析一下r.ParseForm() 。
|
请发表评论