Something about cookie

Monday, Jun 01 17:32, 2009
10 comments/572 hits
之前一直不明白cookie是个什么玩意,这两天看到别人的blog上面有一个功能我非常喜欢,那就是当我在他的blog上留言之后,我再次访问的时候,我就不用再次填入个人信息了,看起来非常之nb。后来发现他是用cookie实现的。实际上浏览器里面有一个cookie的玩意,cookie记录了一些基于站点的数据。

比如我留言之后,在我的浏览器里就留下了三个cookie,分别记录了我在该站点上的用户名,邮箱和网址,这样我下次登录该站点的时候,浏览器会自动把这些cookie信息发送过去,那么服务器就可以得到这些信息,从而显示在相关的地方。

明白了这个东西之后,我发现cookie也just so so啊,没什么神秘的。不就是需要一个把数据输送到用户浏览器的cookie和从cookie中读取数据的两个操作嘛。哈哈。

但是这两个操作怎么实现呢?尤其是在app engine上怎么实现呢?app engine的源代码就是金库啊,我想起来本地调试的时候,登录之后会被记住,这肯定就是cookie了,一查,果然是在cookie里发现了,然后就开始狂找对应的源代码,最后在tools\dev_appserver_login.py的函数LoginCGI里面找到了写cookie的代码,哈哈,赶紧学习。

通过阅读源代码,发现python自带了一个Cookie的类,用以处理这些事情。然后阅读cookie.py的月代码,发现it提供了三种cookie:SimpleCookie,SerialCookie和SmartCookie。而在SDK中使用的是SimpleCookie,由于我也不用是你么cpickle所以也就是用了SimpleCookie。
SimpleCookie的操作方法类似于dict,另外提供了一个load函数,可以把用户通过浏览器传送过来的cookie字符串转化为SimpleCookie对象。

对于读cookie,由于我之前就发现了os.environ中包含了cookie信息,然后加上SimpleCookie的load方法,那么就搞定了。写cookie呢?原始就是往sys.sdout写SimpleCookie对象就行了。

最后还有一个小插曲。在搞定了cookie之后,我看了cookie的RFC 2109,发现我之前使用的cookie的属性expires在RFC2109里解释如下:
Netscape's original proposal defined an Expires header that took a
date value in a fixed-length variant format in place of Max-Age:
他们就为了长度一定就使用那么负责的日期字符串,然后在处理的时候还要再转化为秒,他们完全不知道我使用了如下变态的方法构造出了这个GMT的expires时间:
datetime.datetime.now()+timedelta(days=365)).strftime("%a, %d-%b-%Y %H:%M:%S GMT")

马上就把expires换成了max-age,改进之后的代码如下:
##########写Cookie ############
cookies = Cookie.SimpleCookie()
cookies['comm_name'] = comment.author 
cookies['comm_name']['path'] = '/'
cookies['comm_name']['max-age'] = 3600*24*365
cookies['comm_email'] = comment.authorEmail  
cookies['comm_email']['path'] = '/'
cookies['comm_email']['max-age'] = 3600*24*365
cookies['comm_url'] = comment.authorWebsite 
cookies['comm_url']['path'] = '/'
cookies['comm_url']['max-age'] = 3600*24*365
output_headers = []
output_headers.append('%s\r\n' % cookies)
for header in output_headers:
  sys.stdout.write(header)  

##########读Cookie ############
 cookies = os.environ.get('HTTP_COOKIE', None)
if cookies is not None:
  user_cookie = Cookie.SimpleCookie()
  user_cookie.load(cookies)
  try:
    comm_name = user_cookie['comm_name'].value
    comm_email = user_cookie['comm_email'].value
    comm_url = user_cookie['comm_url'].value
  except KeyError:
    pass        
Over,大功告成!
Author: gzguoer Categories: mindcyclone Tags: BBBlogCookiepython