今天碰到一个头疼的问题, 本想在用户认证之后,给用户生成一个票据(Ticket),存储到浏览器的cookie中, 下次用户使用网站的时候就不需要重新登陆。 在Firefox上开发, 测试,一切OK, 跑到IE上傻眼了,就是不行。 折腾了好一会, 才找到了原因, 浏览器差异真让人头疼啊。
下面是后台的java代码:
//Cookie一年有效
authTicket.setMaxAge(365*24*60*60);
getResponse().addCookie(authTicket);
通过Fiddler查看IE的Http Request和Response报文,发现响应头中包含了如下设置Cookie的信息:
通过Firebug(Firefox的插件)查看Firefox的Http Request和Response报文, 响应头一样。
以为是哪里设置错了, 于是查看了google登陆的过程的Http Request和Response,响应头如下:
可以看到,google的cookie过期是通过Expires控制的,如果选择在本地保存认证信息的话,保存时间为10年。 Expires和Max-Age有什么不同呢? 查看了一下w3c的介绍,其中只有Max-Age的说明。 在网上搜索了一下,好像Expires是旧的标准,现在要使用Max-Age了
set-cookie = "Set-Cookie:" cookies
cookies = 1#cookie
cookie = NAME "=" VALUE *(";" cookie-av)
NAME = attr
VALUE = value
cookie-av = "Comment" "=" value
| "Domain" "=" value
| "Max-Age" "=" value
| "Path" "=" value
| "Secure"
| "Version" "=" 1*DIGIT
Max-Age=delta-seconds
Optional. The Max-Age attribute defines the lifetime of the
cookie, in seconds. The delta-seconds value is a decimal non-
negative integer. After delta-seconds seconds elapse, the client
should discard the cookie. A value of zero means the cookie
should be discarded immediately.
心情很冷, 继续试了各种方法, 未果, 上网搜索, 看到下面一篇文章, 关于中文保存在cookie中的问题
http://topic.csdn.net/u/20090601/17/6960784f-dccc-4361-b778-f31d52faa3c0.html
收到启发, 想可能是因为 KBrN/ylttjzMdpjClXwc6j4n07ZPXUwyBo5y3xofyv2jvkIoNAYFxA== 中包含了/和=两个需要编码的字符,所以IE解析上除了问题? 于是通过下面的方法,对该字符串进行HTML编码, 再存放到Cookie中
//authTicket.setPath("/");
getResponse().addCookie(authTicket);
再次测试, OK... 相当的无语
结语:
虽然w3c上没提编码的事情,但是也没说这样会出问题, 这种问题也没法指责IE了, 只能贴在这里做个备忘, 相比之下Firefox的处理perfect, 再次赞一下Firefox。