[TOC]
## cookie的种植
浏览器自己并不能决定是否设置cookie(当然你可以通过调试器手动往里添加cookie),在它第一次访问服务器的时候,服务器如果有需要会向浏览器传达**种植**cookie的命令,这样在它第二次访问服务器的相同地址时会带上这个种植的cookie
## cookie的设置
### 设置单个cookie
```
res.setHeader('Set-Cookie','name=ahhh; Path=/read; Max-Age=30; Expires=Fri, 16 Mar 2018 16:15:22 GMT; HttpOnly; Secure');
```
可以发现**一个**cookie内部是使用 `;空格 ` 来分隔cookie-param的
服务器设置了cookie以后,在响应头中会多一个`Set-Cookie`字段
```
//res中
Set-Cookie: name=ahhh; Path=/read; Max-Age=30; Expires=Fri, 16 Mar 2018 16:15:22 GMT; HttpOnly; Secure
```
### cookie参数
cookie参数主要是针对 `作用域`、`有效时间` 两个方面。只有在规定的范围内,cookie才会显示、生效。
作用域的修饰包括 :
- `Domain` : 访问的域名必须是Domain规定的域名
- `Path` : 必须是以规定的Path的**开头的**(比如/read,/read/1,/read/1/2)路径才能访问该cookie
- `HttpOnly` : 只有通过 http请求才能查看到cookie,**不再能**通过浏览器控制台查看,这意味着浏览器端不再能手动更改服务器所种植的cookie(但我们仍然能通过curl等其它方式作为客户端传递'虚假'cookie)
- `Secure`:必须是https协议才能查看
有效时间的修饰包括
- `Max-Age`:相对时间,单位为S,express中设置时单位为毫秒
![](https://box.kancloud.cn/62c2304b698267223498caffa44709f0_513x165.png)
- `Exipres`:绝对时间,且为UTC格式,express中设置时单位为毫秒
Max-Age和Expires的区别在于,Max-Age的值是相对时间,也就是说你只需要设置存货多久(howlong),而Expires要先获取当前时间(Date.now()),在这个时间的基础之上再加上存货时间
虽然设置不一样,但最终它们呈现在浏览器application中都是一样的,以一种日期格式显现(而不是时间戳)
![](https://box.kancloud.cn/011f1be2bd40eab7385a4a5b9695a3a2_215x59.png)
### 设置多个cookie
node中允许我们通过数组的形式设置多个cookie
```
req.setHeader('Set-Cookie',[cookie1,cookie2...])
```
cookie之间有逗号隔开,每个cookie中的参数用`;空格`隔开
注意,不要妄图想通过设置多次Set-Cookie来达到设置多个cookie的目的,因为前面的是会被后面的覆盖的
但,话又说回来,实际上在响应报文里,多个cookie的设置的确是通过设置多个Set-Cookie字段来实现的
```
Set-Cookie: ahhh=111; Path=/read; Max-Age=10; HttpOnly; Expires=Fri, 16 Mar 2018 16:29:56 GMT
Set-Cookie: age=123
```
嗯,注意区分,虽然最底层是通过设置多个Set-Cookie字段实现多个cookie的设置,但Node.JS提供给我们的API却不是这样的,我们需要在一次setHeader Set-Cookie的设置里,通过传递一个数组的形式来设置多个cookie。
## cookie的获取
```
req.headers['cookie']
```
cookie获取时**不会**显示cookie的参数设置,另外如果有多个cookie,它们之间是用 `;空格` 隔开的
```
ahhh=111; age=123
```
## cookie失效情景
- 指定了path,只会在指定path下才看得到cookie,**甚至是在浏览器的cookie查看器中也是!**
- 请留意是否开启了`Secure`,开启的话只能在https下访问到该cookie
## 关于中文字符
设置cookie是不能直接放中文的,会报错
![](https://box.kancloud.cn/45619f67597a41e54e63a8cf83b52f0c_600x207.png)
固需要使用`encodeURIComponent`进行编码,
再获取这种带中文字符编码的cookie时也需要`decodeURIComponent`进行解码
## Express中的cookie设置
```
res.cookie('name','ahhh',{expires:new Date(Date.now()+10*1000)});
res.cookie('name','ahhh',{maxAge:10*1000});
```
```
req.headers.cookie; //name=ahhh;[空格]age=11
```
### cookie-parser
将headers里的cookie挂在了req上
并且解析成了对象
注意express获取cookie,是用`req.cookies`(**s**),有s!!(而原生的是没有s)
```
app.use(cookieParser());
console.log(req.cookies);
<<<输出
{
name:ahhh
,age:11
}
```
### express中的cookie参数
统一都是小驼峰命名
### 支持设置带中文的cookie
express会自动进行编码
![](https://box.kancloud.cn/02da2778eb8aaa0128e173e6ecfcb24a_307x115.png)