Python中的Cookies和HTTP
我想在我的 BaseHTTPRequestHandler
子类中“获取”客户端发送的 cookies。
首先,我不太确定在一个典型的 HTTP 请求和响应中,头信息的发送顺序是怎样的。根据我的理解,事件的顺序是这样的:
- 客户端发送请求(包括方法、路径、HTTP 版本、主机和所有头信息)。
- 服务器回应一个响应代码,然后发送一堆自己的头信息。
- 服务器接着发送响应的主体内容。
那么,客户端的 POST 数据到底是什么时候发送的呢?在上面描述的顺序中,会不会有重叠的情况发生?
其次,什么时候可以安全地假设服务器已经收到了“Cookie”头信息?在服务器调用 self.send_response
时,所有的客户端头信息都应该已经接收完了吗?在 HTTP 通信中,什么时候是查看 self.headers
中 cookie 头信息的合适时机呢?
第三,Python 中解析 cookies 的标准方法是什么?我现在认为应该先实例化一个 Cookie.SimpleCookie
,然后把 cookie 头信息中的数据以某种方式传入它。不过,这个问题变得更加复杂,因为 Cookie 类在处理 HTTPRequestHandler 接口时显得有些笨重。为什么 Cookie.output()
的输出不以换行符结尾,以便能适应 self.wfile.write(cookie.output())
,或者干脆省略掉隐式提供的头名称,以便能很好地适应 self.send_header("Set-Cookie", cookie.output())
?
最后,Cookie
模块中的 cookie 类给人一种它们是字典的字典的错觉。在 cookie 中为不同的键赋值,并不会把更多的数据打包到 cookie 中,而是生成了更多的 cookies……看起来都是在同一个类中,每个都生成自己的 Set-Cookie 头信息。将多个值打包到 cookie 中的最佳实践是什么呢?
2 个回答
这里有一个简单的方法,可以在不使用任何第三方库的情况下获取 cookies。虽然这个方法只解决了问题的一部分,但可能正是大多数“访问者”最想要的答案。
import Cookie
def do_GET(self):
cookies = {}
cookies_string = self.headers.get('Cookie')
if cookies_string:
cookies = Cookie.SimpleCookie()
cookies.load(cookies_string)
if 'my-cookie' in cookies:
print(cookies['my-cookie'].value)
HTTP是一种请求/响应的协议,简单来说就是发送请求和接收响应的过程,没有重叠的部分;当你使用POST方法时,POST的内容就是请求的一部分。
所有的头信息也都是请求的一部分,包括Cookie:
如果有的话(当然也可能没有这个头,比如当浏览器禁用了cookie的时候)。所以每次收到请求并处理时,记得查看一下头信息。
我不太明白你说的“第三个”问题是什么。如果cookie里没有换行符,那就不会插入换行符,这有什么好奇怪的呢? 补充: 后面会解释。
关于第四点,我觉得你可能把cookie和“morsel”(小块)搞混了。在HTTP响应中,Set-Cookie头的数量没有限制,那这有什么问题呢?
补充: 你可以选择给output
传递最多三个参数:你想要在每个morsel输出中的属性集合(默认是None
,表示所有属性),你想在每个morsel前面使用的头字符串(默认是Set-Cookie:
),以及你想在morsel之间使用的分隔字符串(默认是\r\n
)。所以看起来你想用cookie的方式是单个morsel(否则你就不能把字符串放进一个头里,而你似乎很想这样做):在这种情况下
thecookie.output(None, '')
会给你正好想要的字符串。只需创建多个SimpleCookie
实例,每个实例包含一个morsel(因为一个morsel正好适合放进一个头里!)。