Before we start talking, let's take a look a simple example of use form, save it as login.gtpl
in your project folder.
<html>
<head>
<title></title>
</head>
<body>
<form action="/login" method="post">
Username:<input type="text" name="username">
Password:<input type="password" name="password">
<input type="submit" value="Login">
</form>
</body>
</html>
This form will submit to /login
in server. After user clicked log in button, the data will be sent to login
handler in server router. Then we need to know it uses POST method or GET.
It's easy to know through http
package, let's see how to handle form data in log in page.
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"strings"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //Parse url parameters passed, then parse the response packet for the POST body (request body)
// attention: If you do not call ParseForm method, the following data can not be obtained form
fmt.Println(r.Form) // print information on server side.
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!") // write data to response
}
func login(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method) //get request method
if r.Method == "GET" {
t, _ := template.ParseFiles("login.gtpl")
t.Execute(w, nil)
} else {
r.ParseForm()
// logic part of log in
fmt.Println("username:", r.Form["username"])
fmt.Println("password:", r.Form["password"])
}
}
func main() {
http.HandleFunc("/", sayhelloName) // setting router rule
http.HandleFunc("/login", login)
err := http.ListenAndServe(":9090", nil) // setting listening port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
Now we know use r.Method
to get request method, and it returns a string like "GET", "POST", "PUT", etc.
In function login
, we use r.Method
to check if it's a log in page or log in process logic, which means you just open this page, or you are trying to log in. Serve shows page only when it uses GET method, process log in logic when it uses POST method.
You should see following interface after you opened http://127.0.0.1:9090/login
in your browser.
Figure 4.1 User log in interface
Server will not print anything after we typed user name and password because handler doesn't parse form until we call r.ParseForm()
. Let's add r.ParseForm()
before fmt.Println("username:", r.Form["username"])
, compile and test again. You should see information is printed in server side now.
r.Form
contains all request arguments, like query-string in URL, data in POST and PUT. If the data have conflicts like have same name, it will save into a slice with multiple values. In Go documentation, it says Go will save data of GET and POST in different places.
Try to change value of action in form http://127.0.0.1:9090/login
to http://127.0.0.1:9090/login?username=astaxie
in file login.gtpl
, test again, and you will see the slice is printed in server side.
Figure 4.2 Server prints request data
The type of request.Form
is url.Value
, it saves data with format key=value
.
v := url.Values{}
v.Set("name", "Ava")
v.Add("friend", "Jess")
v.Add("friend", "Sarah")
v.Add("friend", "Zoe")
// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"
fmt.Println(v.Get("name"))
fmt.Println(v.Get("friend"))
fmt.Println(v["friend"])
Tips Request has ability to access form data by method FormValue()
. For example, you can change r.Form["username"]
to r.FormValue("username")
, and it calls r.ParseForm
automatically. Notice that it returns the first value if there are arguments with same name, and it returns empty string if there is no such argument.
- Directory
- Previous section: User form
- Next section: Verification of inputs