Skip to content

Latest commit

 

History

History
107 lines (82 loc) · 4.08 KB

File metadata and controls

107 lines (82 loc) · 4.08 KB

4.1 Process form inputs

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.

Links