Cookie 故障排除——案例研究






2.87/5 (4投票s)
2007年1月15日
8分钟阅读

32721
如何排除与 Cookie 相关的问题
几天前,我的一位同事问了一个非常简单的问题……“我们有任何文档可以讨论 Cookie 的故障排除方面的一般性问题吗?”。不知何故,我感到很惊讶,我想好吧,让我给你一个详细的答案……然后我想,好吧……也许我应该详细地写一篇博客,现在,我正在这样做。
在我们深入研究 Cookie 的故障排除之前,我们需要确切地知道它们是什么以及它们如何工作。一旦你知道了事物是如何 *确切地* 工作的,你就能很容易地发现任何异常!
让我从头开始……很久很久以前,有一份 RFC :o) RFC2109,它讨论了 HTTP 状态管理机制。最终它被 RFC2965 取代。另一份关于最佳实践的 RFC 在 RFC2964。它们谈到了 Cookie 以及如何使用它们进行状态管理,所以我不打算为你朗读这些故事。不是我不喜欢它……而是它们有点太长了,而且……它们可能相当无聊(取决于你的品味)!
看看我能否用一些工具和其他花絮来让它变得有趣。在我看来,做一些实际练习对记住概念很有帮助。所以,首先在你的电脑上安装 Fiddler,从 http://www.fiddlertool.com/fiddler/ 下载。我将在接下来的内容中大量使用它!如果你认为这篇博文太长而浪费了你的时间,请随时发表评论。
练习 1:
1. 在 C:\Inetpub\wwwroot\ 中创建一个名为 CookieTest.asp 的页面
2. 在记事本中打开 CookieTest.asp 并添加以下行……
<% =Now() %>
3. 打开 IE 浏览器。选择“工具”->“Fiddler”以启动 Fiddler。
4. 在右上角,你会看到一个名为“请求构建器”(Request Builder)的选项卡。
5. 在地址栏中输入 https:///CookieTest.asp,然后单击“执行”(Execute)按钮。
6. 在左窗格中,你会看到一个条目出现,其“主机”(Host)列为 localhost,“URL”列为 /CookieTest.asp。双击该条目。
7. 现在在中右侧窗格中,你会看到 **Headers(标头)**。
8. 查看 Cookie/Login 中写了什么。如果你没有更改任何默认设置,你应该会看到类似以下内容……
Set-Cookie: ASPSESSIONIDSCBCTCAS=COCDMHCAJCFOACMDNLPILFKB; path=/
9. 重复步骤 5-9 几次,你会发现每次该标头信息都会发生变化……
Set-Cookie: ASPSESSIONIDSCBCTCAS=EOCDMHCACFBMJOPONIHNBNKK; path=/
问题 1:思考一下……这个 Cookie 最初是怎么出现的??正如你所见,我们在代码中除了打印时间之外,什么都没做!
答案:ASP 需要会话状态来维护静态 Cookie
<摘录>
ASP 会为每个请求的 .asp 文件发送一个不同的 ASPSessionID cookie(作用域为应用程序,即请求的 .asp 文件的虚拟目录),直到会话状态被触发。一旦在会话变量(标量变量或对象实例)中存储了某些内容,或者应用程序的 Global.asa 文件中的 Session_OnStart 事件被触发,会话状态就会被触发,该用户的 SessionID 会在该用户会话超时或被放弃之前固定。
</摘录>
问题 2:不建议关闭 ASP 会话状态,但如果你的应用程序根本不使用会话……为什么还要打开它并影响性能!那么,如何在 Active Server Pages 和 IIS 中关闭 ASP 会话状态?
答案:在 Active Server Pages 和 IIS 中关闭 ASP 会话状态
练习 2:
1. 单击“开始”,指向“所有程序”,单击“管理工具”,然后单击“Internet 信息服务”。
2. 右键单击你的网站,然后单击“属性”。
3. 单击“主目录”(Home Directory)选项卡。
4. 单击“配置”(Configuration),然后单击“选项”(Options)选项卡。
5. 单击以取消选中“启用会话状态”(Enable Session State)复选框。
6. 重复“练习 1”中的步骤 3-8,并验证你是否还能看到 ASPSessionID!理想情况下,你不应该看到。
问题 3:我正在从 IE 使用 https:///CookieTest.asp,而 Fiddler 似乎没有捕获我的请求,有什么问题?
练习 3:
1. 打开 IE 并启动 Fiddler。
2. 输入 https:///CookieTest.asp 并按 Enter。切换到 Fiddler,你会发现请求没有到达。但既然你看到了输出,那不是事实。那么,出了什么问题??嗯,老实说,我不知道根本原因,因为我无法访问 Fiddler 的代码。我不知道为什么它不捕获 https:///,尽管它是一个基于代理的工具。好消息是,有一个变通方法。
3. 打开 Windows 资源管理器并导航到 C:\<WINDOWS>\system32\drivers\etc
4. 在记事本中打开 hosts 文件,并添加另一行,例如……
127.0.0.1 http://www.localhost.com/
5. 保存 hosts 文件并返回 IE 窗口
6. 尝试 http://www.localhost.com/CookieTest.asp。你不仅会在浏览器中看到输出,还会发现 Fiddler 能够捕获它。
这种方法的好处是,你现在可以像平常一样使用 IE 来调试你的网站,并且同时在 Fiddler 中看到输出。另外,你不需要每次都构建你的请求。只需像往常一样浏览,然后切换到 Fiddler 进行分析。
问题 4:如何创建 Cookie 并查看它们?
练习 4:
1. 再次打开 CookieTest.asp 文件,并将代码修改如下并保存。
<%
Response.Write(Now() & "<BR>")
Response.Cookies("Cool")="My First Cookie!"
%>
2. 为了清晰起见,你可以在 Fiddler 中选择“编辑”->“删除”->“所有会话”(Edit->Remove->All Sessions)来清除历史记录。
3. 打开 IE 并使用 Fiddler 运行,浏览到 http://www.localhost.com/CookieTest.asp。
4. 切换到 Fiddler 并双击选择 http://www.localhost.com/ 的条目。
5. 现在在中右侧窗格中,你会看到 **Headers(标头)**。
6. 你会发现以下内容……
Set-Cookie: Cool=My+First+Cookie%21; path=/
Set-Cookie: ASPSESSIONIDCSSDABRB=FBCJOAKBFODEBMLACHEAEKCC; path=/
问题 5:我可以创建多个 Cookie 并在 Fiddler 中全部查看吗?
答案:是的
练习 5:
1. 打开 CookieTest.asp 文件,并将代码修改如下并保存。
<%
Response.Write(Now() & "<BR>")
Response.Cookies("Cool")="My First Cookie!"
Response.Cookies("Test1")="Test 1"
Response.Cookies("Test2")="Test 2"
%>
2. 重复练习 4 的步骤 2-6,你应该能看到以下内容……
Set-Cookie: Test2=Test+2; path=/
Set-Cookie: Test1=Test+1; path=/
Set-Cookie: Cool=My+First+Cookie%21; path=/
Set-Cookie: ASPSESSIONIDCSSDABRB=FBCJOAKBFODEBMLACHEAEKCC; path=/
注意
你可以创建 Cookie 键。
Response.Cookies("Cool")("Key1")="My First Cookie Key!"
Response.Cookies("Cool")("Key2")="Checking"
另外,如果你为任何 Cookie 定义了键,你不能同时在 Cookie 中存储常规数据……我的意思是……
Response.Cookies("Cool")("Key1")="My First Cookie Key!"
Response.Cookies("Cool")("Key2")="Checking"
Response.Cookies("Cool")="Will this work?"
Fiddler 会显示类似以下内容(这意味着“Will this work?”这个文本永远消失了)……
Set-Cookie: Cool=Key1=My+First+Cookie+Key%21&Key2=Checking; path=/
因此,底线是,如果你使用键,不要直接在 Cookie 中存储数据!
问题 6:我们是否会因为任何 Cookie 限制而丢失 ASP 会话?
练习 6:是的,306070
<摘录>
如果 Web 应用程序使用超过 19 个自定义 Cookie,ASP 会话状态可能会丢失。Internet Explorer 4.0 及更高版本允许每个域总共 20 个 Cookie。因为 ASPSessionID 是一个 Cookie,如果你使用 20 个或更多自定义 Cookie,浏览器将被迫丢弃 ASPSessionID Cookie 并丢失会话。
</摘录>
问题 7:Internet Explorer 中创建的 Cookie 的数量或大小是否有任何限制?
答案:是的,请阅读以下 KB Internet Explorer 中 Cookie 的数量和大小限制
问题 8:如何分析 IIS 日志以查找 Cookie?
答案:非常简单……你需要确保已启用扩展日志记录。
1. 单击“开始”,指向“所有程序”,单击“管理工具”,然后单击“Internet 信息服务”。
2. 右键单击你的网站,然后单击“属性”。
3. 转到“网站”(Web Site)选项卡,并确保选中了“启用日志记录”(Enable Logging)。在该面板中单击“属性”。
4. 单击“扩展属性”(Extended Properties)选项卡。
5. 选中“扩展属性”(Extended Properties),并确保选中了 **Cookie**
6. 这是我在 Windows XP 上的 IISLog……“C:\WINDOWS\system32\Logfiles\W3SVC1”。
7. 这是我的一个条目……
10:20:19 127.0.0.1 - W3SVC1 RAHULSONI 127.0.0.1 80 GET /CookieTest.asp - 200 0 356 421 31 HTTP/1.1 http://www.localhost.com/ Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727) Test2=Test+2;+Test1=Test+1;+Cool=Key1=My+First+Cookie+Key%21&Key2=Checking;+ASPSESSIONIDASSDBBRB=OOELMDKBDECAFOGFBNEEHOOH -
8. 注意你如何看到由分号分隔的 Cookie。例如,如果你看到很多 Cookie,并且你担心会因为 Cookie 过多而丢失会话(参考问题 6),你可以通过计算 IISLogs 中的“;”来轻松确定 Cookie 的数量。
问题 9:你似乎会丢失每个网站/虚拟文件夹的每一个会话,无论你做什么。有什么办法可以解决吗?
答案:大多数情况下,这是由于不允许的字符引起的。我们已经看到“_”导致了很多与会话相关的问题。参考 909264
问题 10:我的常规 Cookie 可以正常工作,但无 Cookie 就不行。这是一个已知问题吗?
答案:是的……“可能”。无论如何检查一下!
问题 11:微软有哪些文档讨论 Cookie?
答案:嗯,有不少……但这里有一个链接,它是一个总链接,指向多个不同且相关的文章……并且是必读的! Cookie 说明
如果你无论如何都读到这里了,并且还想继续,请尝试这些……
1. ASP.NET 中的 Cookie 基础 - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vbtchaspnetcookies101.asp
2. 理解表单身份验证票证和 Cookie - http://support.microsoft.com/kb/910443
3. Cookie 会损害安全吗? - http://www.webopedia.com/DidYouKnow/Internet/2002/Cookies.asp
4. Fiddler PowerToy - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwebgen/html/IE_IntroFiddler.asp
5. 会话状态 - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconSessionState.asp
祝好!
Rahul