Cookie详解

Cookie 为解决 HTTP 无状态而生。

Cookie 的实现原理

服务器在第一次响应的时候,通过 set-cookie 响应头,将需要使用的数据发送到浏览器,浏览器会自动将其作为 Cookie 数据保存。在下一次请求时,会自动携带。

Cookie 的容量限制

单条存储有大小限制大概在 2-4KB 左右,在同源策略下,总共限制大概在 50-200 条左右。

Cookie 的属性

Name

1、Cookie 的存储方式类似于 key-value 形式,name 可以理解为 key;

2、同源策略下,name 不能重复,否则后者覆盖掉前面的。

3、虽然允许中文存储,但是尽量不要使用中文存储,有的浏览器、有的场景下,会有兼容性问题,导致乱码,name 尽量别是中文。

Value

1、Cookie 的实际值

2、存储后是字符串

3、存储中文的话,需要进行编码,读取的时候再行解码。

4、引用类型数据,先转 JSON 字符串存储,读取时在解析 JSON

Domain

Cookie 所在的域,不能跨域读写,默认存储在本域,也可以存储在本域的父级域名、根域之下

Path

Cookie 存储的路径,如果不做说明的话,默认存储是当前路径,但是其余路径的界面,就无法读取。一般情况都是存储到根目录,即 / 目录。

Expires/Max-Age

Cookie 的过期时间 / 最大时效,默认为 session 或者 / ,证明在浏览器关闭之后,就会时效。Cookie 没有永久存储的方法,但是可以通过设置无限大的时间来解决。

Size

Cookie 的大小,单位为字节,显示当前 Cookie 所占空间大小

HttpOnly

是否仅用于传输。如果该栏目为勾选状态,说明该条 cookie 是 JS 无法读取、写入的,只能通过服务器进行读写。

Secure

是否仅适用于https,如果此项勾选,该条 cookie 仅在 https 下才能生效

SameSite

是否防止跨域发送。属性说明如下:

strict:严格模式,只有同站才能发送cookie;

lax:relax的缩写,宽松模式,只有安全的跨站可以发送cookie;

none:禁止samesite的限制,必须配合secure才能使用;

Partition Key

Cookie 分区,和 SameSite = None 一样。

Priority

属性有三种: Low、Medium、High,当 Cookie 的数量超过限制时,浏览器会清除一部分 Cookie。清除哪些合适呢?Priority 属性用来定义 Cookie 的优先级,低优先级的 Cookie 会优先被清除。

客户端 Cookie 的使用方法

写入

- ---- ---
	--- - --- - - - ---------
-

读取

- -----
	-------
		-------------- - -
			- - - ----------
			---------- - -----
				- --------
			-
		--
	---
		- --
	-
-

删除

- -----
	--- - --- - - - - ---------
-

清除

- ----
	- - - -------- -----
	-----
		- -- - - ---- ---- -
			--- - ---- - - - - ---------
		-
	-
-

服务端 Cookie 的使用方法

NodeJS 的 Koa 框架

- - - -----
- - - -----

- --- - - ----
- --------- - - ----

-------------- - --- - -
	- -
	---------- ---
	- -
	----- - -----------
--

---------------------

-------- -- - -
	----- - - - ---
---

Java 的 SpringBoot 框架

package xxx.controller;

import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/cookie")
public class CookieController {

	@GetMapping("/set")
	public String setCookie(HttpServletResponse --------) {
		Cookie ------ = new Cookie("user", "test-cookie");
		--------.addCookie(------);
		return "Cookie  set successfully";
	}

	@GetMapping("/get")
	public String getCookie(@CookieValue(---- = "user", -------- = false) String -----------) {
		return -----------;
	}

	@GetMapping("/get-all")
	public Object getALLCookie(HttpServletRequest -------) {
		Cookie[] ------- = -------.getCookies();
		Map <String, String> -- = new HashMap <> ();
		if (------- != null) {
			for (int - = 0; - < -------.------; -++) {
				--.put(-------[-].getName(), -------[-].getValue());
			}
		}
		return --;
	}

	@GetMapping("/remove")
	public String removeCookie(HttpServletResponse --------) {
		Cookie ------ = new Cookie("user", "");
		------.setMaxAge(0);
		--------.addCookie(------);
		return "Cookie  remove successfully";
	}

	@GetMapping("/clear")
	public String clearCookie(HttpServletRequest -------, HttpServletResponse --------) {
		Cookie[] ------- = -------.getCookies();
		if (------- != null) {
			for (int - = 0; - < -------.------; -++) {
				Cookie ------ = new Cookie(-------[-].getName(), "");
				------.setMaxAge(0);
				--------.addCookie(------);
			}
		}
		return "Cookie  clear successfully";
	}

}
我宁愿犯错误,也不愿什么都不做。