[TOC] ## **HTTP协议** 在http协议的请求头(Request Header)(参考1)中,有一个`Cookie`字段。可以在http请求中加入相应的cookie信息。 在http协议的响应头(Response Header)中,有一个`Set-Cookie字`段,通过该字段客户端可以保存服务端返回的cookie信息,以便在下次请求的时候携带上cookie ## **Go语言Cookie结构体** 在go语言中的net/http包中,Cookie的定义如下: ``` 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 Raw string Unparsed []string // Raw text of unparsed attribute-value pairs } ``` 解释一下上面的MaxAge字段,MaxAge字段为一个整型: * 当大于0时,表示该cookie可以被保存多长时间(以秒为单位),此时浏览器一般会把它保存在本地文件中,浏览器退出后重新登录,此cookie依旧可用; * 当MaxAge为0时,该cookie会被浏览器保存在内存中,浏览器没有退出的话,一直可以使用该cookie,但退出后就会不能被使用; * 当MaxAge小于0时,表示服务器告诉浏览器立即删除该cookie。 ## **示例** 下面以一个go程序(参考2)来模拟cookie: 当访问`/readcookie`路径时,服务器在http协议的response body中返回浏览器携带的cookie信息;如果浏览器未携带cookie,则返回提示信息 当访问`/writecookie`路径时,服务器在http的response header中的`Set-Cookie`字段返回一个cookie,该cookie在浏览器再次访问/readcookie路径时将被使用 当访问`/deletecookie`路径时,服务器将cookie的MaxAge字段设为-1,告诉浏览器立即删除该cookie 服务器代码如下: ``` package main import ( "net/http" ) func SayHello(w http.ResponseWriter, req *http.Request) { w.Write([]byte("Hello")) } func ReadCookieServer(w http.ResponseWriter, req *http.Request) { // read cookie cookie, err := req.Cookie("testcookiename") if err == nil { cookievalue := cookie.Value w.Write([]byte("<b>cookie的值是:" + cookievalue + "</b>\n")) } else { w.Write([]byte("<b>读取出现错误:" + err.Error() + "</b>\n")) } } func WriteCookieServer(w http.ResponseWriter, req *http.Request) { cookie := http.Cookie{Name: "testcookiename", Value: "testcookievalue", Path: "/", MaxAge: 86400} http.SetCookie(w, &cookie) w.Write([]byte("<b>设置cookie成功。</b>\n")) } func DeleteCookieServer(w http.ResponseWriter, req *http.Request) { cookie := http.Cookie{Name: "testcookiename", Path: "/", MaxAge: -1} http.SetCookie(w, &cookie) w.Write([]byte("<b>删除cookie成功。</b>\n")) } func main() { http.HandleFunc("/", SayHello) http.HandleFunc("/readcookie", ReadCookieServer) http.HandleFunc("/writecookie", WriteCookieServer) http.HandleFunc("/deletecookie", DeleteCookieServer) http.ListenAndServe(":8082", nil) } ``` 接下来我们第一次访问 `x.x.x.x:8082/readcookie`,如下没有任何cookie信息 ![](https://img.kancloud.cn/15/ac/15acd8f8e2107c9e970ea972e4bc37eb_447x117.png) 然后我们访问`x.x.x.x:8082/writecookie` ![](https://img.kancloud.cn/6a/8a/6a8a7f042507220d2c8b692b4a564590_413x106.png) 然后,我们再访问`x.x.x.x:8082/readcookie`,此时我们发现这一次浏览器携带保存的cookie ![](https://img.kancloud.cn/d7/19/d719ac149626a6f229771a36686621b9_408x104.png) 我们可以查看当前请求所携带的cookie信息(右击firefox的导航栏 --》 菜单栏 --》 工具 --》 页面信息 --》 安全 --》 cookie) ![](https://img.kancloud.cn/45/3a/453a91945b9d0b37ac9ef24b71723724_616x475.png) 关闭浏览器,再次访问`x.x.x.x:8082/readcookie`,还是能看到cookie信息,说明浏览器把它保存在本地文件中了 ![](https://img.kancloud.cn/d7/19/d719ac149626a6f229771a36686621b9_408x104.png) 接下来,我们访问`x.x.x.x:8082/deletecookie` ![](https://img.kancloud.cn/c4/ab/c4ab2feb62798503c82b04a98f54c999_404x108.png) 然后,再访问`x.x.x.x:8082/readcookie`,发现cookie已经被浏览器删掉了,所以本次请求没有cookie信息 ![](https://img.kancloud.cn/15/ac/15acd8f8e2107c9e970ea972e4bc37eb_447x117.png) ## **参考** [1] https://zh.wikipedia.org/wiki/HTTP%E5%A4%B4%E5%AD%97%E6%AE%B5 [2] https://studygolang.com/articles/5905