[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信息

然后我们访问`x.x.x.x:8082/writecookie`

然后,我们再访问`x.x.x.x:8082/readcookie`,此时我们发现这一次浏览器携带保存的cookie

我们可以查看当前请求所携带的cookie信息(右击firefox的导航栏 --》 菜单栏 --》 工具 --》 页面信息 --》 安全 --》 cookie)

关闭浏览器,再次访问`x.x.x.x:8082/readcookie`,还是能看到cookie信息,说明浏览器把它保存在本地文件中了

接下来,我们访问`x.x.x.x:8082/deletecookie`

然后,再访问`x.x.x.x:8082/readcookie`,发现cookie已经被浏览器删掉了,所以本次请求没有cookie信息

## **参考**
[1] https://zh.wikipedia.org/wiki/HTTP%E5%A4%B4%E5%AD%97%E6%AE%B5
[2] https://studygolang.com/articles/5905
- 应用层
- HTTP
- Cookie
- Session
- HTTP报文格式
- HTTP的Header字段
- HTTPS
- 简介
- 原理
- RSA加密与解密
- 证书签名与验证
- TLS双向认证
- openssl命令汇总
- DNS
- DNS的记录类型
- DNS的报文格式
- FAQ
- 传输层
- TCP
- CloseWait
- 网络层
- IPv6
- 链路层
- 链接层基础知识
- VLAN
- Linux网络收发包
- 网卡收包
- 网卡发包
- 收发包FAQ
- LVS
- 安装-DR模式
- 基本原理
- Ipvsadm命令
- Netfilter
- Netfilter简介
- 注册钩子函数
- Netfilter中数据包流向
- Iptables的数据结构
- 连接跟踪
- 初识连接跟踪
- 连接跟踪详解
- 连接跟踪数据结构
- 数据包与连接的状态
- NAT
- IPVS
- KubeProxy的IPVS模式
- Linux虚拟网络设备
- 虚拟网络设备简介
- Tap
- VethPair
- Vlan
- Vxlan
- Flannel的VXLAN原理
- Openstack的VXLAN原理
- VXLAN总结
- Bridge
- 给容器设置主机网段IP
- Macvlan
- Ipvlan
- IPIP
- IPIP使用介绍
- IPIP源码分析
- Limdiag网络
- 详细设计
- kubeovn
- IP命令
- Calico
- Calico常见问题
- ARP无响应
- 其他