bigywater.tech
Flask · 46

Cookie 的读写过程

set_cookie 写出的头长什么样?中文和特殊字符怎么处理?删除 cookie 为什么删不掉?请求里的 Cookie 头怎么解析?超过大小限制会怎样?这篇逐项打印。

4093
MAX_COOKIE_SIZE 的默认值(超限只警告)
第一个
请求里重复的 cookie 名取到的值
path / domain
删除 cookie 时必须与设置时一致的两项

set_cookie 的各个参数

实测 · 本机执行输出
  Set-Cookie: plain=v1; Path=/
  Set-Cookie: opts=v2; Expires=Fri, 02 Oct 2026 04:28:31 GMT; Max-Age=3600; Secure; HttpOnly; Path=/app; SameSite=Lax
  Set-Cookie: cn="\344\270\255\346\226\207 \347\251\272\346\240\274\073\345\210\206\345\217\267\054\351\200\227\345\217\267\"\345\274\225\345\217\267"; Path=/
  Set-Cookie: exp=v; Expires=Tue, 01 Jan 2030 00:00:00 GMT; Path=/

上一篇:Last-Modified 与缓存响应;下一篇:Signed Cookie;安全属性专题:HttpOnly、Secure、SameSite。

delete_cookie

实测 · 本机执行输出
  Set-Cookie: plain=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/
  Set-Cookie: opts=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/app

读取请求里的 Cookie

实测 · 本机执行输出
  正常           Cookie: 'a=1; b=2'                   → {'a': '1', 'b': '2'}
  带引号的值        Cookie: 'a="x y"'                    → {'a': 'x y'}
  重复的名字        Cookie: 'a=1; a=2'                   → {'a': '1'}
  没有等号         Cookie: 'a=1; b; c=3'                → {'a': '1', 'b': '', 'c': '3'}
  值里有等号        Cookie: 'a=b=c'                      → {'a': 'b=c'}
  空值           Cookie: 'a=; b=2'                    → {'a': '', 'b': '2'}
  名字大小写        Cookie: 'A=1; a=2'                   → {'A': '1', 'a': '2'}
  百分号          Cookie: 'a=%E4%B8%AD'                → {'a': '%E4%B8%AD'}
  原始 UTF-8     Cookie: 'a=ä¸\xad'                   → {'a': 'ä¸\xad'}
  分号后没空格       Cookie: 'a=1;b=2'                    → {'a': '1', 'b': '2'}
  带空格的名字       Cookie: 'my cookie=1'                → {}

测试客户端的 cookie jar

实测 · 本机执行输出
  GET /set 之后 GET /read 看到的 cookies: {'cn': '中文 空格;分号,逗号"引号', 'exp': 'v', 'plain': 'v1'} (opts 的 path=/app 与 secure,所以 /read 没带它)
  jar 里的键: ['cn(path=/)', 'exp(path=/)', 'opts(path=/app)', 'plain(path=/)']

中文值的往返

实测 · 本机执行输出
  中文那条 cn 在客户端看到的原始值: '"\\344\\270\\255\\346\\226\\207 \\347\\251\\272\\346\\240\\274\\073\\345\\210\\206\\345\\217\\267\\054\\351\\200\\227\\345\\217\\267\\"\\345\\274\\225\\345\\217\\267"'
  再发回来后 request.cookies["cn"] = '中文 空格;分号,逗号"引号'

大小限制

实测 · 本机执行输出
  MAX_COOKIE_SIZE = 4093
  设置 5000 字节的 cookie:状态 200 | 警告: ["The 'big' cookie is too large: the value was 5000 bytes but the header required 12 extra bytes. The final size was 5012 bytes but the limit is 4093 by"]
  Set-Cookie 头长度: 5012

samesite 与 Partitioned

实测 · 本机执行输出
  samesite='Lax'    → s=1; Path=/; SameSite=Lax
  samesite='Strict' → s=1; Path=/; SameSite=Strict
  samesite='None'   → s=1; Secure; Path=/; SameSite=None
  samesite='bogus'  → ValueError: SameSite must be 'Strict', 'Lax', or 'None'.
  samesite=None     → s=1; Path=/
  partitioned=True: p=v; Secure; Path=/; Partitioned

分步演示

Cookie
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:浏览器对 Partitioned cookie 的真实支持、domain 参数与子域共享(见第 29 篇)、浏览器对超大 cookie 的丢弃行为、cookie 前缀(__Host-、__Secure-)的约束
    京ICP备2026067502号-1京公网安备11010502063487号