# 21.23. `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`。

exception `http.cookies.``CookieError`

  由于 RFC 2109无效：不正确的属性，不正确的Set-Cookie标题等而导致异常失败

class `http.cookies.``BaseCookie`([input])

  此类是类字典对象，其键是字符串，其值为`Morsel`实例。请注意，将键设置为值时，首先将该值转换为包含键和值的`Morsel`。

  如果给定输入，则将其传递到`load()`方法。

class `http.cookies.``SimpleCookie`([input])

  此类派生自`BaseCookie`，并覆盖`value_decode()`和`value_encode()`为标识，`str()`分别。

也可以看看

模块`http.cookiejar`
  web 客户端的HTTP cookie处理。`http.cookiejar`和`http.cookies`模块不依赖于彼此。
RFC 2109 - HTTP状态管理机制
  这是由该模块实现的状态管理规范。

## 21.23.1. Cookie对象

`BaseCookie.``value_decode`(val)

  从字符串表示返回解码值。返回值可以是任何类型。此方法在`BaseCookie`中不执行任何操作 - 它存在，因此可以覆盖。

`BaseCookie.``value_encode`(val)

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

  一般来说，应该是`value_encode()`和`value_decode()`是value_decode范围内的反转。

`BaseCookie.``output`(attrs=None, header='Set-Cookie:', sep='\r\n')

  返回适合作为HTTP头发送的字符串表示。attrs和头被发送到每个`Morsel`的`output()`方法。sep用于将标头连接在一起，默认情况下是组合`'\r\n'`（CRLF）。

`BaseCookie.``js_output`(attrs=None)

  返回一个可嵌入的JavaScript代码段，如果在支持JavaScript的浏览器上运行，则会如同发送HTTP标头一样运行。

  attrs的含义与`output()`中的含义相同。

`BaseCookie.``load`(rawdata)

  如果rawdata是字符串，请将其解析为`HTTP_COOKIE`，并添加在`Morsel`中找到的值。如果它是一个字典，它等效于：

      for k, v in rawdata.items():
          cookie[k] = v

## 21.23.2. Morsel对象

class `http.cookies.``Morsel`

  抽象一个键/值对，它有一些 RFC 2109属性。

  Morsels是类似字典的对象，其键集是常量 - 有效的 RFC 2109属性，

  - `expires`
  - `path`
  - `comment`
  - `domain`
  - `max-age`
  - `secure`
  - `version`
  - `httponly`

  属性`httponly`指定Cookie仅在HTTP请求中传输，不能通过JavaScript访问。这旨在减轻某些形式的跨站点脚本。

  键是不区分大小写的，其默认值为`''`。

  在版本3.5中更改： `__eq__()`现在将`key`和`value`纳入考虑。

`Morsel.``value`

  Cookie的值。

  自版本3.5起已弃用：指定为`value`；请改用`set()`。

`Morsel.``coded_value`

  Cookie的编码值 - 这是应该发送的内容。

  自版本3.5之后已弃用：分配到`coded_value`；请改用`set()`。

`Morsel.``key`

  Cookie的名称。

  自版本3.5之后已弃用：分配到`key`；请改用`set()`。

`Morsel.``set`(key, value, coded_value)

  设置键，值和coded_value属性。

  自版本3.5后已弃用：未记录的LegalChars参数将被忽略，并将在以后的版本中删除。

`Morsel.``isReservedKey`(K)

  是否K是`Morsel`的键集合的成员。

`Morsel.``output`(attrs=None, header='Set-Cookie:')

  返回Morsel的字符串表示形式，适合作为HTTP标头发送。默认情况下，包括所有属性，除非给出attrs，在这种情况下，它应该是要使用的属性列表。标题默认为`"Set-Cookie:"`。

`Morsel.``js_output`(attrs=None)

  返回一个可嵌入的JavaScript代码段，如果在支持JavaScript的浏览器上运行，则会如同发送HTTP标头一样运行。

  attrs的含义与`output()`中的含义相同。

`Morsel.``OutputString`(attrs=None)

  返回一个表示Morsel的字符串，没有任何周围的HTTP或JavaScript。

  attrs的含义与`output()`中的含义相同。

`Morsel.``update`(values)

  使用字典中的值值更新Morsel字典中的值。如果值 dict中的任何键不是有效的 RFC 2109属性，则引发错误。

  在3.5版本中更改：无效键出现错误。

`Morsel.``copy`(value)

  返回Morsel对象的浅副本。

  在版本3.5中更改：返回Morsel对象而不是dict。

`Morsel.``setdefault`(key, value=None)

  如果密钥不是有效的 RFC 2109属性，则引发错误，否则与`dict.setdefault()`相同。

## 21.23.3. 示例

以下示例演示如何使用`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