请求和响应
Request结构
- URL字段
- Header字段
- Body字段
- Form, PostForm, MultipartForm字段
在处理器函数中,我们可以通过Request获取各个字段的详细信息
func get_request_value(w *http.ResponseWriter, r *http.Request) {
h := r.Header
brower := r.Header.Get("User-Agent")
fme.Fprintln(w, h)
body := make([]byte, r.ContentLength)
r.Body.Read(body)
fmt.Fprintln(w, string(body))
}
Go与HTML表单
用户在表单中输入的数据会以键值对的形式记录在请求的主体中,其中表单中的enctype属性决定了以何种形式发送键值对。默认属性值为application/x-www-form-urlencoded,这个属性会把表单中的数据编码一个连续的长查询字符串,另一种编码方式为multipart/form-data,表单中的数据会被转换为一条MIME报文,每个键值对都构成了这个报文的一部分。简单来说,当表单只需要传送简单数据时,默认编码更加简单,高效;而当表单需要传输大量数据(如文件)时,使用后一种编码方式会更好。有些时候,用户可以通过Base64编码,以文本方式传送二进制数据。
使用Request结构获取表单数据的一般步骤是:
- 调用ParseForm或者ParseMultipartForm方法进行语法分析
- 访问Form, PostForm, MultipartForm等字段获取数据
func get_form_data1(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fmt.Fprintln(w, r.Form)
// PostForm字段只支持默认编码,并且只返回表单值,不返回URL查询值
fmt.Fprintln(w, r.PostForm)
}
当使用multipart/form-data编码时,表单数据会被存储到MultipartForm字段中
func get_form_data2(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(1024)
fmt.Fprintln(w, r.MultipartForm)
}
我们也可以使用FormValue或者PostFormValue快速获取表单值,也两个方法会自动调用ParseForm或者ParseMultipartForm方法,其中PostFormValue只会返回表单键值对而不会返回URL键值对
使用FormFile方法可以快速的获取被上传的文件
func process(w http.ResponseWriter, r *http.Request) {
file, _, err := r.FormFile("upload")
if err == nil {
data, err := ioutil.ReadAll(file)
if err == nil {
fmt.Fprintln(w, string(data))
}
}
}
ResponseWriter
- Write 接收一个字节数组,并写入到HTTP响应主体中
- WriteHeader 改变HTTP响应状态码
- Header 修改HTTP响应首部
package main
import (
json2 "encoding/json"
"fmt"
"net/http"
)
type Post struct {
User string
Threads []string
}
func writeExample(w http.ResponseWriter, r *http.Request) {
str := `<html>
<head><title>Go</title></head>
<body><h1>Hello world</h1></body>
</html>`
w.Write([]byte(str))
}
func writeHeaderExample(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(501)
fmt.Fprintln(w, "No such service, try next door")
}
func headerExample(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Location", "http://baidu.com")
w.WriteHeader(302)
}
func jsonExample(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
post := &Post{
User: "authetic",
Threads: []string{"first", "second"},
}
json, _ := json2.Marshal(post)
w.Write(json)
}
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/write", writeExample)
http.HandleFunc("/writeheader", writeHeaderExample)
http.HandleFunc("/redirect", headerExample)
http.HandleFunc("/json", jsonExample)
server.ListenAndServe()
}
cookie
Go与cookie
没有设置Expires字段的通常被成为会话cookie,浏览器关闭或刷新cookie就会消失,设置了Expires字段的通常被称为持久cookie,在过期时间之前会一直存在。
func set_cookie(w http.ResponseWriter, r *http.Request) {
c1 := http.Cookie{
Name: "first_cookie",
Value: "Go Web",
HttpOnly: true,
}
c2 := http.Cookie{
Name: "second_cookie",
Value: "Go Web",
HttpOnly: true,
}
http.SetCookie(w, &c1)
http.SetCookie(w, &c2)
}
func get_cookie(w http.ResponseWriter, r *http.Request) {
// h := r.Header["Cookie"]
cl, err := r.Cookie("first_cookie")
if err != nil {
fmt.Fprintln(w, "Something wrong")
}
cs := r.Cookies()
fmt.Fprintln(w, cl)
fmt.Fprintln(w, cs)
}
cookie实现闪现消息
func setMessage(w http.ResponseWriter, r *http.Request) {
msg := []byte("Hello Go")
c := http.Cookie{
Name: "flash",
Value: base64.URLEncoding.EncodeToString(msg),
}
http.SetCookie(w, &c)
}
func showMessage(w http.ResponseWriter, r *http.Request) {
c, err := r.Cookie("flash")
if err != nil {
if err == http.ErrNoCookie {
fmt.Fprintln(w, "No message found")
}
} else {
rc := http.Cookie{
Name: "flash",
MaxAge: -1,
Expires: time.Unix(1, 0),
}
http.SetCookie(w, &rc)
val, _ := base64.URLEncoding.DecodeString(c.Value)
fmt.Fprintln(w, string(val))
}
}
|
请发表评论