【问题标题】:Classic ASP: Multiple ASPSESSIONID in cookies经典 ASP:cookie 中的多个 ASPSESSIONID
【发布时间】:2012-10-08 14:33:06
【问题描述】:

我遇到了一个经典 ASP 页面的问题,我只是在 3 天后无法解决。

页面正在使用 Sessions - 有时会发生 ASPSESSIONID cookie 在 Request.ServerVariables("HTTP_COOKIE") 中设置了两次。这会导致 ASP 页面在刷新页面时在两个会话之间跳转。

我已经编写了一个测试页面,它输出当前的 SessionId、服务器软件和 HTTP_COOKIE 值。

样本输出:


会话 ID:308542840

会话超时:20 分钟

服务器软件:Microsoft-IIS/6.0

HTTP_COOKIE:ASPSESSIONIDQCBATRAD=MBHHDGCBGGBJBMAEGLDAJLGF; ASPSESSIONIDQCCDTTCB=PGHPDGCBPLKALGGKIPOFIGDM


为什么有两个 ASPSESSIONID? 当我刷新页面时,它会随机输出两个会话 ID 之一。

这是一个显示 IE9 中的问题的截屏视频: http://prinz-alexander.at/asp_test.avi

这个错误在ie8和ie9中经常出现。

只需执行以下操作即可重现问题:

  1. 完全关闭 IE8 或 IE9
  2. 启动IE8或IE9并打开http://www.pfiffikus.at/pfiffikus/tests/
  3. 页面加载后立即刷新页面多次

如果您重复此步骤,则 HTTP_COOKIE 会随机(并非总是)填充两个不同的 ASPSESSIONID。

asp 测试文件只输出mentiod 值,源代码中没有其他内容。

这是asp测试文件的代码:

<% If trim(Session("test_val")) = "" Then
     Dim my_num
     Randomize
     number = Int((rnd*1000))+1
     Session("test_val") = number
   End If
%>

<b>Session ID:</b>
<% response.write(Session.SessionId) %><br /><br />

<b>Session("test_val"):</b>
<% response.write(Session("test_val")) %><br /><br />

<b>Session Timeout:</b>
<% response.write(Session.Timeout) %> minutes<br /><br />

<b>Server Software:</b>
<% response.write(Request.ServerVariables("SERVER_SOFTWARE")) %><br /> <br />

<b>HTTP_COOKIE:</b> <% response.write(Request.ServerVariables("HTTP_COOKIE")) %>

如何避免 cookie 中出现多个 ASPSESSIONId?

感谢您的帮助!

【问题讨论】:

  • 张贴一些您已分配会话的代码。
  • 我已将代码添加到我最初的问题中...
  • 您配置了一个网络花园(具有多个进程的应用程序池)?
  • @AnthonyWJones 我只是虚拟主机的用户,但我没有管理权限。我还能查出是否配置了网络花园吗?为什么这种情况会出现问题,您会建议什么配置?

标签: session iis cookies asp-classic iis-6


【解决方案1】:

我能够使用 Javascript 删除这些 cookie。

只需将下一个脚本添加到登录页面的末尾即可。 这将在用户登录网站之前删除所有“ASPSESSIONIDXXXXXXX”cookie:

<script type="text/javascript">
    //Clear any session cookies
    (function(){
        var cookiesArr = document.cookie.split("; ");
        for (var i = 0; i < cookiesArr.length; i++) {
            var cItem = cookiesArr[i].split("=");
            if (cItem.length > 0 && cItem[0].indexOf("ASPSESSIONID") == 0) {
                deleteCookie(cItem[0]);
            }
        }

        function deleteCookie(name) {
            var expDate = new Date();
            expDate.setTime(expDate.getTime() - 86400000); //-1 day
            var value = "; expires=" + expDate.toGMTString() + ";path=/";
            document.cookie = name + "=" + value;
        }
    })();
</script>

【讨论】:

  • 这样做很荒谬,这正是我必须做的,以避免使用数百个 aspsessionid 来最大化 cookie 大小!
【解决方案2】:

您可以使用 URL 重写模块在设置会话 cookie 时对其进行重命名,并使用入站重写规则将其再次还原。当会话名称 ID 更改时会出现多个会话 cookie,但是通过为会话 cookie 指定一个名称并将 ID 包含在 cookie 本身中,一次只会有一个会话 cookie。

在 web.config 中使用这些重写规则来改变

ASPSESSIONIDXXXXXXXX=YYYYYYYYYYYYYYYYYYYYYYYY

进入

session=XXXXXXXX/YYYYYYYYYYYYYYYYYYYYYYYY

然后在入站请求时再次将其还原(因此它仍然可以被 IIS 读取):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
        <rules>
            <clear />
            <!-- "HTTP_COOKIE" must be added to the "allowed server variables" in IIS under URLRewrite -->
            <rule name="session cookie revert">
                <match url="(.*)" />
                <conditions>
                    <add input="{HTTP_COOKIE}" pattern="(.*)session=([0-9a-zA-Z]+)\/([0-9a-zA-Z]+)(.*)" />
                </conditions>
                <serverVariables>
                    <set name="HTTP_COOKIE" value="{C:1}ASPSESSIONID{C:2}={C:3}{C:4}" />
                </serverVariables>
                <action type="None" />
            </rule>
        </rules>
        <outboundRules>
            <rule name="session cookie rewrite">
                <match serverVariable="RESPONSE_Set_Cookie" pattern="ASPSESSIONID([0-9a-zA-Z]+)=([0-9a-zA-Z]+)(.*)" negate="false" />
                <!-- Set the session cookie as HttpOnly during the rewrite. Classic ASP doesn't 
                do this by default, but it's important for preventing XSS cookie stealing. 
                You could also add "; Secure" if you only want the session cookie to be passed 
                over an SSL connection, although this also means the cookie can only be set over 
                an SSL connection too, which could be a problem when testing on localhost. -->
                <action type="Rewrite" value="session={R:1}/{R:2}{R:3}; HttpOnly" />
            </rule>     
        </outboundRules>
    </rewrite>
  </system.webServer>
</configuration>

【讨论】:

  • 谢谢,对于使用经典 ASP 的网站来说,这是一个很好的长期解决方案。它不会删除现有的 ASPSESSIONID cookie,但会阻止它们将来再次出现。
【解决方案3】:

这个问题也困扰了我很久。而且我解决不了。

这与浏览器无关。我的Chrome、Firefox、IE都有这个问题。

有时我可以在一页中看到 20 多个 ASPSESSIONIDXXXX cookie。

最后我必须使用javascript清除旧的ASPSESSIONID***并保留最新的。

function clearASPSESSIONID(){
    var cks = document.cookie.match(/\b(ASPSESSIONID[A-Z]+)(?==)/g),
        lskey = 'oldASPSESSIONID-'+location.protocol+'//'+location.host,
        old = window.localStorage ? localStorage.getItem(lskey) : '',
        keep, i;
    for(i=0;i<cks.length;i++){
        if((old && old.indexOf(cks[i])<0) || i==cks.length-1){
            keep = cks[i];
        }
    }
    for(i=0;i<cks.length;i++){
        if(keep != cks[i]){
            document.cookie = cks[i] + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
        }
    }
    if(window.localStorage){
        localStorage.setItem(lskey, keep ? keep : '');
    }
}
clearASPSESSIONID();

【讨论】:

  • 您看到 20+ ASPSESSIONIDxxxxxx(注意 x 的数量)的原因可能是 1)您有一个由多个服务器组成的池,每个服务器都不知道其他服务器 2)cookie 设置为整个域,而不是主机。您可以通过限制名称来解决此问题。见:stackoverflow.com/questions/7854288/aspsessionid-name-changeHTH
  • 有时可行,有时却不行……真的很奇怪。
【解决方案4】:

转到应用程序池“高级设置”并将“最大工作进程”设置为 1。

【讨论】:

  • 这不仅仅是网络花园设置,它还使用了负载均衡器!杰出的。我没有想到。
  • 这并不能解决问题...还有很多。
【解决方案5】:

在 global.asa 文件中:

Sub Session_OnStart

    Dim cookie, cookies : cookies = Split(Request.ServerVariables("HTTP_COOKIE"),";")
    For Each cookie In cookies
        cookie = Trim(Split(cookie,"=")(0))
        If Left(cookie,12) = "ASPSESSIONID" Then
            Response.AddHeader "Set-Cookie", cookie&"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/"
        End If
    Next

End Sub

【讨论】:

    【解决方案6】:

    也许稍后,但可能会有用,因为没有可接受的答案。

    在应用程序池中,在回收选项中,检查是否没有 过早回收您的应用程序,否则您将以 为您重生的每个新应用程序提供 ASPSESSIONIDXXXXXXX。

    有几种回收条件。 我错误地将“最小请求数”设置为1并得到 每个请求的 ASPSESSIONID

    【讨论】:

      【解决方案7】:

      您在用户的会话中分配了一个值。尝试像这样获取您的会话并为每个用户分配不同的唯一值

      <% 
      Session("test") = "test value" 
      a=Session("test")
      response.Write(a)
      %>
      

      【讨论】:

      • 好的...我刚刚编辑了我的测试页面并添加了您的建议(我正在向会话添加一个随机数,另请参阅初始问题中的编辑代码)。当我在 IE9 中测试页面时,我通常仍然会得到两个 ASPSessionId,当我在 cookie 中有这些到 ASPSessionId 时,在每个页面请求中,它都会从一个 SessionId 跳转到另一个(每个会话都有自己的“test_val”)-“有趣“关于它的事情是,我在 cookie 中得到的 ASPSessionId 永远不会超过两个 - 这是我忘记提及的事情......
      • 不要像“response.write Session.SessionId”那样响应。像 response.write(Session("test")).another 一样简单地响应。每次刷新页面时,数字都会更改。因此,只有在用户登录时才能分配会话。
      • ...我在开头添加了If语句,Session“test_val”只设置了一次。如果我刷新页面,数字保持不变 - 在您的情况下,每次请求后数字是否仍在变化?
      • 没有我的情况。它是由你决定。你想用你的会话 ID 做什么。我认为您需要阅读有关会话的更多信息。只需阅读页面w3schools.com/asp/asp_sessions.asp
      • 感谢您的链接,但我对会话的工作方式有很好的了解 - 示例工作正常,但我的 ASPSessionID 设置两次(请参阅 HTTP_COOKIE)值仍然存在问题例子。我创建了这个小测试页面来简而言之显示问题,实际应用程序要大得多。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 2021-10-11
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多