1. http.cookies HTTP cookie
http.cookies模块为大多数符合RFC2109的cookie实现一个解析器。这个实现没有标准那么严格,因为MSIE3.0x不支持完整的标准。
1.1 创建和设置cookie
可以用cookie为基于浏览器的应用实现状态管理,因此,cookie通常由服务器设置,并由客户存储和返回。下面给出一个最简单的例子,创建一个cookie设置一个键值对。
from http import cookies c = cookies.SimpleCookie() c['mycookie'] = 'cookie_value' print(c)
输出是一个合法的Set-Cookie首部,可以作为HTTP响应的一部分传递到客户。
1.2 Morsel
还可以控制 cookie的其他方面,如到期时间、路径和域。实际上,cookie的所有RFC属性都可以通过表示cookie值的Morse1对象来管理。
from http import cookies import datetime def show_cookie(c): print(c) for key, morsel in c.items(): print() print('key =', morsel.key) print(' value =', morsel.value) print(' coded_value =', morsel.coded_value) for name in morsel.keys(): if morsel[name]: print(' {} = {}'.format(name, morsel[name])) c = cookies.SimpleCookie() # A cookie with a value that has to be encoded # to fit into the header c['encoded_value_cookie'] = '"cookie,value;"' c['encoded_value_cookie']['comment'] = 'Has escaped punctuation' # A cookie that only applies to part of a site c['restricted_cookie'] = 'cookie_value' c['restricted_cookie']['path'] = '/sub/path' c['restricted_cookie']['domain'] = 'PyMOTW' c['restricted_cookie']['secure'] = True # A cookie that expires in 5 minutes c['with_max_age'] = 'expires in 5 minutes' c['with_max_age']['max-age'] = 300 # seconds # A cookie that expires at a specific time c['expires_at_time'] = 'cookie_value' time_to_live = datetime.timedelta(hours=1) expires = (datetime.datetime(2020, 4, 8, 18, 30, 14) + time_to_live) # Date format: Wdy, DD-Mon-YY HH:MM:SS GMT expires_at_time = expires.strftime('%a, %d %b %Y %H:%M:%S') c['expires_at_time']['expires'] = expires_at_time show_cookie(c)
这个例子使用两个不同的方法设置到期的cookie。其中一个方法将max-age设置为一个秒数,另一个方法将expires设置为一个日期时间,达到这个日期时间就会丢弃这个cookie。
Cookie和Morsel对象都相当于字典。Morsel响应一个固定的键集。
expires
path
comment
domain
secure
version
Cookie实例的键是所存储的各个cookie的名。这个信息也可以从Morsel的键属性得到。
1.3 编码的值
cookie首部值必须经过编码才能被正确的解析。
from http import cookies c = cookies.SimpleCookie() c['integer'] = 5 c['with_quotes'] = 'He said, "Hello, World!"' for name in ['integer', 'with_quotes']: print(c[name].key) print(' {}'.format(c[name])) print(' value={!r}'.format(c[name].value)) print(' coded_value={!r}'.format(c[name].coded_value)) print()
Morsel.value是cookie的解码值,而Morsel.coded_value表示总是用来将值传输到客户。这两个值都是串。如果保存到一个cookie的值不是串,那么其将会自动转换为串。
1.4 接收和解析Cookie首部
一旦客户接收到Set-Cookie首部,在后续请求中它会使用一个Cookie首部把这些cookie返回到服务器。到来的Cookie首部串可能包含多个cookie值,由分号分隔(;)。
Cookie: integer=5; with_quotes="He said, "Hello, World!""
取决于Web服务器和框架,可以直接从首部或HTTP_COOKIE环境变量得到cookie。
from http import cookies HTTP_COOKIE = '; '.join([ r'integer=5', r'with_quotes="He said, "Hello, World!""', ]) print('From constructor:') c = cookies.SimpleCookie(HTTP_COOKIE) print(c) print() print('From load():') c = cookies.SimpleCookie() c.load(HTTP_COOKIE) print(c)
要对它们解码,实例化时可以将串(但不包括首部前缀)传递到SimpleCookie,或者使用load()方法。
1.5 候选输出格式
除了使用Set-Cookie首部,服务器还可以提供JavaScript向客户增加cookie。SimpleCookie和Morsel通过js_output()方法来提供JavaScript输出。
from http import cookies import textwrap c = cookies.SimpleCookie() c['mycookie'] = 'cookie_value' c['another_cookie'] = 'second value' js_text = c.js_output() print(textwrap.dedent(js_text).lstrip())
结果是一个完整的script标记,其中包含设置cookie的语句。