20.22. Cookie-HTTP 状态 Management

Note

Cookie模块在 Python 3 中已重命名为http.cookies2to3工具在将源转换为 Python 3 时将自动适应导入。

源代码: Lib/Cookie.py


Cookie模块定义了用于抽象化 cookie 概念(HTTP 状态 Management 机制)的类。它同时支持简单的纯字符串 cookie,并提供抽象化以将任何可序列化的数据类型作为 cookie 值。

该模块以前严格应用了 RFC 2109 RFC 2068规范中描述的解析规则。此后发现,MSIE 3.0x 不遵循那些规范中概述的字符规则,并且当涉及 Cookie 处理时,许多当今的浏览器和服务器也放宽了解析规则。结果,所使用的解析规则不太严格。

字符集string.ascii_lettersstring.digits!#$%&'*+-.^_`|~表示该模块在 Cookie 名称(如key)中允许的有效字符集。

Note

遇到无效的 Cookie 时,会引发CookieError,因此,如果您的 Cookie 数据来自浏览器,则应始终为无效数据做准备,并在解析时捕获CookieError

  • exception Cookie. CookieError

    • 由于 RFC 2109无效而导致异常失败:错误的属性,错误的* Set-Cookie *Headers 等。
    • class * Cookie. BaseCookie([* input *])
    • 此类是类似于字典的对象,其键是字符串,其值是Morsel个实例。请注意,在将键设置为值时,该值首先转换为包含键和值的Morsel

如果给定* input *,则将其传递给load()方法。

    • class * Cookie. SimpleCookie([* input *])
    • 此类从BaseCookie派生,并覆盖value_decode()value_encode()分别作为标识和str()
    • class * Cookie. SerialCookie([* input *])

从 2.3 版开始不推荐使用:从不可信的 cookie 数据中读取腌制的值是一个巨大的安全漏洞,因为可以制作腌制字符串以使任意代码在您的服务器上执行。仅支持向后兼容,finally可能会消失。

    • class * Cookie. SmartCookie([* input *])
    • 此类从BaseCookie派生。如果它是有效的 pickle,它将value_decode()覆盖为pickle.loads(),否则覆盖值本身。除非它是字符串,否则它将value_encode()覆盖为pickle.dumps(),在这种情况下,它将返回值本身。

从 2.3 版开始不推荐使用:SerialCookie中的相同安全警告在此处适用。

需要进一步的安全说明。为了向后兼容,Cookie模块导出一个名为Cookie的类,该类只是SmartCookie的别名。这可能是一个错误,并且可能会在将来的版本中删除。出于与不使用SerialCookie类相同的原因,不应在应用程序中使用Cookie类。

See also

  • Module cookielib

  • 用于 Web * clients *的 HTTP cookie 处理。 cookielibCookie模块彼此不依赖。

  • RFC 2109-HTTP 状态 Management 机制

  • 这是此模块实现的状态 Management 规范。

  • BaseCookie. value_decode(* val *)

    • 从字符串表示形式返回解码后的值。返回值可以是任何类型。此方法在BaseCookie中不执行任何操作-存在,因此可以覆盖它。
  • BaseCookie. value_encode(* val *)

    • 返回一个编码值。 * val *可以是任何类型,但是返回值必须是字符串。此方法在BaseCookie中不执行任何操作-存在,因此可以覆盖它。

通常,应该是value_encode()value_decode()在* value_decode *的范围内是倒数的情况。

  • BaseCookie. output([* attrs * [,* header * [,* sep *]]])
    • 返回适合作为 HTTPHeaders 发送的字符串表示形式。 * attrs header *被发送到每个Morseloutput()方法。 * sep *用于将 Headers 连接在一起,默认情况下为'\r\n'(CRLF)组合。

在版本 2.5 中进行了更改:默认分隔符已从'\n'更改为与 Cookie 规范匹配。

  • BaseCookie. js_output([* attrs *])
    • 返回一个可嵌入的 JavaScript 代码段,如果该代码段运行在支持 JavaScript 的浏览器上,则其行为将与发送 HTTPHeaders 相同。
  • attrs *的含义与output()中的含义相同。
  • BaseCookie. load(* rawdata *)
    • 如果* rawdata *是字符串,则将其解析为HTTP_COOKIE并将在此找到的值添加为Morsel。如果是字典,则等同于:

20.22.2. 杂物

  • 类别 Cookie. Morsel
    • 抽象一个具有一些 RFC 2109属性的键/值对。

杂项是类似于字典的对象,其键集是恒定的,即有效的 RFC 2109属性,即

  • expires

  • path

  • comment

  • domain

  • max-age

  • secure

  • version

  • httponly

属性httponly指定 cookie 仅在 HTTP 请求中传输,并且不能pass JavaScript 访问。目的是减轻某些形式的跨站点脚本编写。

密钥不区分大小写。

2.6 版的新Function:添加了httponly属性。

  • Morsel. value

    • Cookie 的值。
  • Morsel. coded_value

    • Cookie 的编码值-这就是应该发送的值。
  • Morsel. key

    • Cookie 的名称。
  • Morsel. set(* key value coded_value *)

    • 设置* key value coded_value *属性。
  • Morsel. isReservedKey(* K *)

      • K *是否为Morsel的键集的成员。
  • Morsel. output([* attrs * [,* header *]])

    • 返回 Morsel 的字符串表示形式,适合作为 HTTPHeaders 发送。默认情况下,包括所有属性,除非给出* attrs *,在这种情况下,它应该是要使用的属性列表。 * header *默认为"Set-Cookie:"
  • Morsel. js_output([* attrs *])

    • 返回可嵌入的 JavaScript 代码段,如果该代码段在支持 JavaScript 的浏览器上运行,则其行为与发送 HTTPHeaders 的行为相同。
  • attrs *的含义与output()中的含义相同。
  • Morsel. OutputString([* attrs *])
    • 返回代表 Morsel 的字符串,不包含任何 HTTP 或 JavaScript。
  • attrs *的含义与output()中的含义相同。

20.22.3. Example

下面的示例演示了如何使用Cookie模块。

>>> import Cookie
>>> C = Cookie.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 = Cookie.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 = Cookie.SimpleCookie()
>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
>>> print C
Set-Cookie: chips=ahoy
Set-Cookie: vienna=finger
>>> C = Cookie.SimpleCookie()
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
>>> print C
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
>>> C = Cookie.SimpleCookie()
>>> C["oreo"] = "doublestuff"
>>> C["oreo"]["path"] = "/"
>>> print C
Set-Cookie: oreo=doublestuff; Path=/
>>> C["twix"] = "none for you"
>>> C["twix"].value
'none for you'
>>> C = Cookie.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
>>> # SerialCookie and SmartCookie are deprecated
>>> # using it can cause security loopholes in your code.
>>> C = Cookie.SerialCookie()
>>> C["number"] = 7
>>> C["string"] = "seven"
>>> C["number"].value
7
>>> C["string"].value
'seven'
>>> print C
Set-Cookie: number="I7\012."
Set-Cookie: string="S'seven'\012p1\012."
>>> C = Cookie.SmartCookie()
>>> C["number"] = 7
>>> C["string"] = "seven"
>>> C["number"].value
7
>>> C["string"].value
'seven'
>>> print C
Set-Cookie: number="I7\012."
Set-Cookie: string=seven