Go中處理響應
1 概述
Go 語言 HTTP 伺服器,在啟動監聽並處理接收的請求時,會將實現了 http.ResponseWriter
介面的 http.Response
物件作為第一個引數傳遞到請求處理器,示例程式碼:
func main() { // 設定 路由 http.HandleFunc("/", IndexAction)· // 開啟監聽 log.Fatal(http.ListenAndServe(":8888", nil)) } func IndexAction(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`<h1 align="center">來自小韓說課的問候</h1>`)) }
示例程式碼中的引數 w
就是這個響應物件。我們通過該物件完成響應的操作。
2 響應主體
http.ResponseWriter
介面定義了 Write([]byte) (int, error)
方法,來寫(傳送)響應主體。 傳送響應主體前,會檢測是否呼叫了 WriteHeader
方法,如果沒有會先呼叫這個方法完成響應頭的傳送。同時檢測響應頭中是否包含了 Content-Type
,如果沒有,根據響應主體的前 512 個位元組來確定 Content-Type
的值。額外的,若響應主體的長度不到 1KB 同時沒有呼叫 Flush,會自動在響應頭中增加 Content-Length
資訊。
func IndexAction(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`<h1 align="center">來自小韓說課的問候</h1>`)) }
示例程式碼中的 <h1 align="center">來自小韓說課的問候</h1>
就是響應主體部分。實操時,最常見的響應主體響應是模板的解析結果,利用 html/template
包完成,示例程式碼為:
func IndexAction(w http.ResponseWriter, r *http.Request) { // 解析模板檔案 t, _ :=template.ParseFiles("themes/classic/index.html") // 傳送響應主體 t.Execute(w, contents) }
html/template
包的使用會有後續說明。
3 響應頭資訊
http.ResponseWriter
介面定義了 Header() Header
方法,來獲取頭資訊物件,藉助於該物件,可以完成響應頭的操作。頭資訊物件支援 .Get()
、 .Set()
、 .Add()
、 .Del()
操作完成獲取、設定、新增、刪除頭資訊操作。若有多個頭的鍵相同,Header 中儲存為該鍵對應用逗號分隔串聯起來的這些頭的值。
例如,下面程式碼設定響應頭 Content-Type: application/json:
func Test(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") }
設定完的響應頭可以使用 ResponseWriter.WriteHeader(int)
方法傳送,該方法需要響應狀態碼為引數。若每呼叫該方法,則在第一次執行 ResponseWriter.Write([]byte) (int, error)
時自動呼叫,此時響應狀態碼為 http.StatusOK
也就是 200。示例響應 JSON 資料:
func Test(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) // 可有可無 w.Write([]byte(`{"name":"Hank", "gender":"male"}`)) }
4 操作cookie
http.SetCookie(w ResponseWriter, cookie *Cookie)
方法用於在 w 的響應頭中新增 Set-Cookie 頭,頭的值為 Cookie 型別物件。 http.Cookie
型別定義了 Cookie 的屬性,包括 key,值,有效期等,參考 Cookie 定義:
type Cookie struct { Namestring Value string Pathstring// optional Domainstring// optional Expirestime.Time // optional RawExpires string// for reading cookies only // MaxAge=0 means no 'Max-Age' attribute specified. // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0' // MaxAge>0 means Max-Age attribute present and given in seconds MaxAgeint Securebool HttpOnly bool SameSite SameSite Rawstring Unparsed []string // Raw text of unparsed attribute-value pairs }
利用 http.SetCookie()
設定 cookie 的示例如下,設定了 key,value,path,domain,expire:
func Test(w http.ResponseWriter, r *http.Request) { ex := time.Now().Add(23*3600*30*time.Second) http.SetCookie(w, &http.Cookie{ Name:"User", Value:"Hank", Path:"/", Domain:".hellokang.net", Expires:ex, }) }
5 重定向
http.Redirect(w ResponseWriter, r *Request, urlStr string, code int)
可以完成重定向操作,需指定重定向地址 urlStr 和狀態碼 code。演示為:
func Test(w http.ResponseWriter, r *http.Request) { http.Redirect(w,r,"/target/", 301) // Moved Permanently } func Test(w http.ResponseWriter, r *http.Request) { http.Redirect(w,r,"/target/", 302) // Found }
301 永久重定向,302 臨時重定向。
6 響應 404
http.NotFound(w ResponseWriter, r *Request)
方法可以快捷響應 404 。
func Test(w http.ResponseWriter, r *http.Request) { http.NotFound(w, r) // 404 Not Found }