http.cookies
— HTTP 状态管理¶
源代码: Lib/http/cookies.py
http.cookies
模块定义了多个类,用于对 cookie 这一 HTTP 状态管理机制进行抽象。它支持纯字符串 cookie,并提供了一种抽象,允许将任何可序列化的数据类型用作 cookie 值。
该模块最初严格遵循 RFC 2109 和 RFC 2068 规范中描述的解析规则。后来发现 MSIE 3.0x 并未遵循这些规范中列出的字符规则;如今许多浏览器和服务器在处理 cookie 时也放宽了解析规则。因此,该模块现在使用的解析规则比以前稍宽松一些。
字符集 string.ascii_letters
、string.digits
和 !#$%&'*+-.^_`|~:
表示本模块允许在 cookie 名称(作为 key
)中使用的有效字符集合。
在 3.3 版更改: 允许 ':' 作为有效的 cookie 名称字符。
备注
遇到无效 cookie 时,会引发 CookieError
,所以如果你的 cookie 数据来自浏览器,应始终做好应对无效数据的准备,并在解析时捕获 CookieError
。
- class http.cookies.BaseCookie([input])¶
此类是一个类似字典的对象,其键是字符串,值是
Morsel
实例。请注意,在为键设置值时,值会首先被转换为一个包含该键和值的Morsel
。如果提供了 input,它将被传递给
load()
方法。
- class http.cookies.SimpleCookie([input])¶
该类派生自
BaseCookie
并重写了value_decode()
和value_encode()
。SimpleCookie
支持将字符串作为 cookie 值。设置值时,SimpleCookie
会调用内置的str()
将值转换为字符串。从 HTTP 接收到的值将保持为字符串。
参见
http.cookiejar
模块用于 Web 客户端 的 HTTP cookie 处理。
http.cookiejar
和http.cookies
模块彼此独立。- RFC 2109 - HTTP State Management Mechanism
这是本模块所实现的状态管理规范。
Cookie 对象¶
- BaseCookie.value_decode(val)¶
从字符串表示形式返回一个元组
(real_value, coded_value)
。real_value
可以是任何类型。此方法在BaseCookie
中不执行任何解码操作——它的存在是为了被重写。
- BaseCookie.value_encode(val)¶
返回一个元组
(real_value, coded_value)
。val 可以是任何类型,但coded_value
将始终被转换为字符串。此方法在BaseCookie
中不执行任何编码操作——它的存在是为了被重写。通常情况下,在 value_decode 的值域上,
value_encode()
和value_decode()
应该是互逆的。
- BaseCookie.output(attrs=None, header='Set-Cookie:', sep='\r\n')¶
返回一个适合作为 HTTP 标头发送的字符串表示形式。attrs 和 header 会被发送到每个
Morsel
的output()
方法。sep 用于连接各个标头,默认为'\r\n'
(CRLF) 组合。
Morsel 对象¶
- class http.cookies.Morsel¶
抽象了一个键/值对,它具有一些 RFC 2109 属性。
Morsel 是类似字典的对象,其键集是固定的——即有效的 RFC 2109 属性,它们是
httponly
属性指定 cookie 仅在 HTTP 请求中传输,并且不能通过 JavaScript 访问。这旨在减轻某些形式的跨站脚本攻击。samesite
属性控制浏览器何时随跨站请求发送 cookie。这有助于缓解 CSRF 攻击。有效值为 "Strict"(仅随同站请求发送)、"Lax"(随同站请求和顶级导航发送)和 "None"(随同站和跨站请求发送)。使用 "None" 时,还必须设置 "secure" 属性,这是现代浏览器的要求。partitioned
属性向用户代理表明,这些跨站 cookie 应该只在首次设置 cookie 的同一顶级上下文中可用。为了让用户代理接受此设置,你必须同时设置Secure
。此外,建议在设置分区 cookie 时使用
__Host
前缀,使其绑定到主机名而不是可注册域。请阅读 CHIPS (Cookies Having Independent Partitioned State) 以获取完整细节和示例。键名不区分大小写,其默认值为
''
。在 3.7 版更改: 属性
key
、value
和coded_value
是只读的。请使用set()
来设置它们。在 3.8 版更改: 添加了对
samesite
属性的支持。在 3.14 版更改: 添加了对
partitioned
属性的支持。
- Morsel.value¶
cookie 的值。
- Morsel.coded_value¶
cookie 的编码值——这是应该被发送的内容。
- Morsel.key¶
cookie 的名称。
- Morsel.set(key, value, coded_value)¶
设置 key、value 和 coded_value 属性。
- Morsel.output(attrs=None, header='Set-Cookie:')¶
返回 Morsel 的字符串表示形式,适合作为 HTTP 标头发送。默认情况下,包含所有属性,除非提供了 attrs,此时它应该是一个要使用的属性列表。header 默认为
"Set-Cookie:"
。
- Morsel.js_output(attrs=None)¶
返回一个可嵌入的 JavaScript 代码片段,如果在支持 JavaScript 的浏览器上运行,其效果与发送 HTTP 标头相同。
attrs 的含义与在
output()
中的含义相同。
- Morsel.OutputString(attrs=None)¶
返回表示 Morsel 的字符串,不带任何周围的 HTTP 或 JavaScript 代码。
attrs 的含义与在
output()
中的含义相同。
- Morsel.update(values)¶
使用字典 values 中的值更新 Morsel 字典中的值。如果 values 字典中的任何键不是有效的 RFC 2109 属性,则引发错误。
在 3.5 版更改: 对无效键会引发错误。
- Morsel.copy(value)¶
返回 Morsel 对象的浅拷贝。
在 3.5 版更改: 返回一个 Morsel 对象而不是一个字典。
- Morsel.setdefault(key, value=None)¶
如果 key 不是有效的 RFC 2109 属性,则引发错误,否则其行为与
dict.setdefault()
相同。
示例¶
以下示例演示了如何使用 http.cookies
模块。
>>> from http import cookies
>>> C = cookies.SimpleCookie()
>>> C["fig"] = "newton"
>>> C["sugar"] = "wafer"
>>> print(C) # generate HTTP headers
Set-Cookie: fig=newton
Set-Cookie: sugar=wafer
>>> print(C.output()) # same thing
Set-Cookie: fig=newton
Set-Cookie: sugar=wafer
>>> C = cookies.SimpleCookie()
>>> C["rocky"] = "road"
>>> C["rocky"]["path"] = "/cookie"
>>> print(C.output(header="Cookie:"))
Cookie: rocky=road; Path=/cookie
>>> print(C.output(attrs=[], header="Cookie:"))
Cookie: rocky=road
>>> C = cookies.SimpleCookie()
>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
>>> print(C)
Set-Cookie: chips=ahoy
Set-Cookie: vienna=finger
>>> C = cookies.SimpleCookie()
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
>>> print(C)
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
>>> C = cookies.SimpleCookie()
>>> C["oreo"] = "doublestuff"
>>> C["oreo"]["path"] = "/"
>>> print(C)
Set-Cookie: oreo=doublestuff; Path=/
>>> C = cookies.SimpleCookie()
>>> C["twix"] = "none for you"
>>> C["twix"].value
'none for you'
>>> C = cookies.SimpleCookie()
>>> C["number"] = 7 # equivalent to C["number"] = str(7)
>>> C["string"] = "seven"
>>> C["number"].value
'7'
>>> C["string"].value
'seven'
>>> print(C)
Set-Cookie: number=7
Set-Cookie: string=seven