Go 語言的 net/http 包提供了一系列用於表示 HTTP 報文的結構,咱們可使用它
處理請求和發送相應,其中 Request 結構表明了客戶端發送的請求報文,下面讓咱們看
一下 Request 結構體html
Request 結構中的 URL 字段用於表示請求行中包含的 URL,改字段是一個指向
url.URL 結構的指針web
獲取請求的 URL瀏覽器
例如:http://localhost:8080/hello?username=admin&password=123456服務器
注: 經過 r.URL.Path 只能獲得 /helloapp
獲取請求的 URL 後面?後面的查詢字符串post
例如:http://localhost:8080/hello?username=admin&password=123456ui
注: 經過 r.URL.RawQuery 獲得的是 username=admin&password=123456編碼
經過 Request 結果中的 Header 字段用來獲取請求頭中的全部信息,Header 字段
的類型是 Header 類型,而 Header 類型是一個 map[string][]string,string 類型的 key,
string 切片類型的值。url
r.Header指針
map[User-Agent:[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36] Accept:[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,ima ge/apng,*/*;q=0.8] Accept-Encoding:[gzip, deflate, br] Accept-Language:[zh- CN,zh;q=0.9,en-US;q=0.8,en;q=0.7] Connection:[keep-alive] Upgrade-Insecure- Requests:[1]]
方式一:r.Header[「Accept-Encoding」]
方式二:r.Header.Get(「Accept-Encoding」)
請求和響應的主體都是有 Request 結構中的 Body 字段表示,這個字段的類型是
io.ReadCloser 接口,該接口包含了 Reader 接口和 Closer 接口,Reader 接口擁有 Read
方法,Closer 接口擁有 Close 方法
因爲 GET 請求沒有請求體,因此咱們須要在 HTML 頁面中建立一個 form 表單,通
過指定 method=」post」來發送一個 POST 請求
<html> <head> <meta charset="UTF-8"/> </head> <body> <form action="http://localhost:8080/getBody" method="POST" enctype="multipart/form-data"> 用戶名:<input type="text" name="username" /><br/> 密碼:<input type="password" name="password" /><br/> <input type="submit" /> </form> </body> </html>
package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { //獲取內容的長度 length := r.ContentLength //建立一個字節切片 body := make([]byte, length) //讀取請求體 r.Body.Read(body) fmt.Fprintln(w, "請求體中的內容是:", string(body)) } func main() { http.HandleFunc("/getBody", handler) http.ListenAndServe(":8080", nil) }
在瀏覽器上顯示的結果
下面咱們就經過 net/http 庫中的 Request 結構的字段以及方法獲取請求 URL 後面
的請求參數以及 form 表單中提交的請求參數
1) 類型是 url.Values 類型,Form 是解析好的表單數據,包括 URL 字段的 query
參數和 POST 或 PUT 的表單數據。
2) Form 字段只有在調用 Request 的 ParseForm 方法後纔有效。在客戶端,會忽
略請求中的本字段而使用 Body 替代
1) 獲取表單中提交的請求參數(username 和 password)
func handler(w http.ResponseWriter, r *http.Request) { //解析表單 r.ParseForm() //獲取請求參數 fmt.Fprintln(w, "請求參數爲:", r.Form) } //注意:在執行 r.Form 以前必定要調用 ParseForm 方法 //結果 //請求參數爲: map[password:[666666] username:[hanzong]]
<form action="http://localhost:8080/getBody?username=admin&pwd=123456" method="POST"> 用 戶 名 : <input type="text" name="username" value="hanzong"><br/> 密 碼 : <input type="password" name="password" value="666666"><br/> <input type="submit"> </form>
則執行結果以下:
請求參數爲:map[username:[hanzong admin] password:[666666] pwd:[123456]]
1) 類型也是 url.Values 類型,用來獲取表單中的請求參數
func handler(w http.ResponseWriter, r *http.Request) { //解析表單 r.ParseForm() //獲取請求參數 fmt.Fprintln(w, "請求參數爲:", r.PostForm) }
請求參數爲:map[username:[hanzong] password:[666666]]
2) 可是 PostForm 字段只支持 application/x-www-form-urlencoded 編碼,若是
form 表單的 enctype 屬性值爲 multipart/form-data,那麼使用 PostForm 字段
沒法獲取表單中的數據,此時須要使用 MultipartForm 字段
a) 能夠經過 FormValue 方法快速地獲取某一個請求參數,該方法調用以前
會自動調用 ParseMultipartForm 和 ParseForm 方法對錶單進行解析
func handler(w http.ResponseWriter, r *http.Request) { //獲取請求參數 fmt.Fprintln(w, "請求參數username的值爲:", r.FormValue("username")) }
請求參數 username 的值爲: hanzong
a) 能夠經過 PostFormValue 方法快速地獲取表單中的某一個請求參數,該
方法調用以前會自動調用 ParseMultipartForm 和 ParseForm 方法對錶單
進行解析
func handler(w http.ResponseWriter, r *http.Request) { //獲取請求參數 fmt.Fprintln(w, "請求參數 username 的值爲:", r.PostFormValue("username")) }
爲了取得 multipart/form-data 編碼的表單數據,咱們須要用到 Request 結構的
ParseMultipartForm 方法和 MultipartForm 字段,咱們一般上傳文件時會將 form 表單的
enctype 屬性值設置爲 multipart/form-data
1) 表單
<form action="http://localhost:8080/upload" method="POST" enctype="multipart/form-data"> 用 戶 名 : <input type="text" name="username" value="hanzong"><br/> 文件:<input type="file" name="photo" /><br/> <input type="submit"> </form>
1) 後臺處理請求代碼
package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { //解析表單 r.ParseMultipartForm(1024) fmt.Fprintln(w, r.MultipartForm) } func main() { http.HandleFunc("/upload", handler) http.ListenAndServe(":8080", nil) }
3) 瀏覽器顯示結果
&{map[username:[hanzong]] map[photo:[0xc042126000]]}
MuiltipartForm 字段的類型爲 *multipart.Form,multipart 包下 Form 結構的指
針類型
打開上傳的文件
func handler(w http.ResponseWriter, r *http.Request) { //解析表單 r.ParseMultipartForm(1024) fileHeader := r.MultipartForm.File["photo"][0] file, err := fileHeader.Open() if err == nil { data, err := ioutil.ReadAll(file) if err == nil { fmt.Fprintln(w, string(data)) } } }
net/http 提供的 FormFile 方法能夠快速的獲取被上傳的文件,可是隻能處理上
傳一個文件的狀況。
func handler(w http.ResponseWriter, r *http.Request) { file, _, err := r.FormFile("photo") if err == nil { data, err := ioutil.ReadAll(file) if err == nil { fmt.Fprintln(w, string(data)) } } }