Go Web编程 第四章--处理请求

请求和响应

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结构获取表单数据的一般步骤是:

  1. 调用ParseForm或者ParseMultipartForm方法进行语法分析
  2. 访问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()
}

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))
    }
}

猜你喜欢

转载自www.cnblogs.com/authetic/p/10199449.html