## 1 概述
Go 语言 HTTP 服务器,在启动监听并处理接收的请求时,会将实现了 `http.ResponseWriter` 接口的 `http.Response` 对象作为第一个参数传递到请求处理器,示例代码:
```go
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` 就是这个响应对象。我们通过该对象完成响应的操作。
<!-- more -->
## 2 响应主体
`http.ResponseWriter` 接口定义了 `Write([]byte) (int, error)` 方法,来写(发送)响应主体。
发送响应主体前,会检测是否调用了 `WriteHeader` 方法,如果没有会先调用这个方法完成响应头的发送。同时检测响应头中是否包含了 `Content-Type`,如果没有,根据响应主体的前 512 个字节来确定 `Content-Type` 的值。额外的,若响应主体的长度不到 1KB 同时没有调用 Flush,会自动在响应头中增加 `Content-Length` 信息。
```go
func IndexAction(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<h1 align="center">来自小韩说课的问候</h1>`))
}
```
示例代码中的 `<h1 align="center">来自小韩说课的问候</h1>` 就是响应主体部分。实操时,最常见的响应主体响应是模板的解析结果,利用 `html/template` 包完成,示例代码为:
```go
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:
```go
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 数据:
```go
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 定义:
```go
type Cookie struct {
Name string
Value string
Path string // optional
Domain string // optional
Expires time.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
MaxAge int
Secure bool
HttpOnly bool
SameSite SameSite
Raw string
Unparsed []string // Raw text of unparsed attribute-value pairs
}
```
利用 `http.SetCookie()` 设置 cookie 的示例如下,设置了 key,value,path,domain,expire:
```go
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。演示为:
```go
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 。
```go
func Test(w http.ResponseWriter, r *http.Request) {
http.NotFound(w, r) // 404 Not Found
}
```
完!
原文出自:[小韩说课](http://www.hellokang.net/go/go-http-response/)
微信关注:小韩说课
![小韩说课](http://asset.hellokang.net/images/common/xiaohanshuoke_258.jpg)
有疑问加站长微信联系(非本文作者))