在两个页面之间丢失会话变量

Losing session variables between two pages

这很奇怪。我最近将该站点移动到 CF11 上的共享主机(我相信),所以我不知道这是否与此有关。以前没有发生过。

我仍在使用 application.cfm(不是 cfc),它目前看起来像这样:

<CFAPPLICATION 
    NAME="catholicity"
    SESSIONMANAGEMENT="Yes"
    SESSIONTIMEOUT=#CreateTimeSpan(0,2,0,0)#
    CLIENTMANAGEMENT="Yes"
    CLIENTSTORAGE="Cookie"
>

我们的网站 catholicity.co.nz 允许用户添加商家信息。列表过程是分步完成的,首先选择一个类别,然后输入更多详细信息。我们将列表数据存储在名为 "session.post" 的会话变量中。选择类别后,jQuery 代码将所选类别传递给 coldfusion cfc 函数,该函数创建 session.post 并将所选类别添加到其中 (session.post.category)。 jQuery 然后加载一个新页面以输入更多详细信息。我已经确认 jQuery 可以读取在 cfc 中创建的会话范围。在第二页上,会话范围似乎丢失了。 Session.post 当我在这个新页面的顶部转储会话范围时没有出现。

javascript 重定向代码如下所示:

top.location.href="/post/post.cfm?cat=" + cat + "&subcat=" + subcat + "&mode=" + mode;

直接从 returns session.post

的 cfc 中读取 cat 和 subcat 值
<cffunction.....>
   ...
   <cfset session.post.category = nCategoryId & "^" & sCategory>
   <cfset session.post.subcategory = arguments.id & "^" & sSubcategory>
   <cfset session.post.prev="subcategory_id">
   <cfset session.post.next="details">
   ...
   <cfreturn session.post>
</cffunction>

奇怪的是,如果用户在创建新的商家信息时登录,则不会发生此问题。我不确定为什么,因为登录会创建一个名为 session.user 的单独会话变量,据我所知,session.usersession.post.

之间没有任何联系

此问题可在 http://www.catholicity.co.nz 进行测试,然后单击顶部的“添加业务”。我在第一页和第二页上转储了会话和客户端范围,并在从初始 cfc 调用回调时发出 JS 警报。

编辑

我的 application.cfm 看起来像这样:

<CFAPPLICATION 
    NAME="catholicity"
    SESSIONMANAGEMENT="Yes"
    SESSIONTIMEOUT=#CreateTimeSpan(0,2,0,0)#
    CLIENTMANAGEMENT="Yes"
    CLIENTSTORAGE="Cookie"
>

<cfif structKeyExists(session,"cfid")>
    <cfcookie name="cfid" value="#session.cfid#" expires="NOW">
    <cfcookie name="cftoken" value="#session.cftoken#" expires="NOW">
</cfif>

<cfif structKeyExists(url, "logout")>
    <cfset session.user.authenticated = 0>
</cfif>

<cfparam name="session.cfid" default="">
<cfparam name="session.cftoken" default="">

<cfparam name="session.mode" default="temp">

<cfparam name="session.user.authenticated" default="0">
<cfparam name="session.user.confirmed" default="0">
<cfparam name="session.user.disabled" default="0">
<cfparam name="session.user.id" default="">
<cfparam name="session.user.email" default="">
<cfparam name="session.user.contact_name" default="">

<cferror type="exception" template="/error.cfm">

<cfscript>
    application.accepted_docs = "application/pdf,application/msword,application/vnd.ms-excel,text/plain,vnd.ms-word.document.12,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    application.accepted_images = "image/jpg,image/gif,image/jpeg,image/png,image/x-png,image/pjpeg ";
    application.accepted_videos = "video/x-flv,video/mp4,video/x-msvideo,video/x-ms-asf,video/x-ms-wmv,audio/x-ms-wma";
....
</cfscript>

<cflock name="#APPLICATION.applicationName#" 
        type="Exclusive" 
        timeout="20" 
        throwontimeout="Yes"> 

    <cfparam name="APPLICATION.SessionTracker" default=#StructNew()#> 

    <cfscript>
        sUserInfo = StructNew();
        sUserInfo.Address="#CGI.REMOTE_ADDR#";
        sUserInfo.CFID="#session.cfid#";
        sUserInfo.Token="#session.cftoken#";
        sUserInfo.Address="#CGI.REMOTE_ADDR#";
        sUserInfo.Time="#Now()#";
        sUserInfo.Template="#CGI.CF_Template_Path#";
        ID = "#session.cfid##session.cftoken#";
    </cfscript>

   <CFSET dummy = StructInsert(APPLICATION.SessionTracker, ID, sUserInfo, true)> 
</cflock>

我试过注释掉可能不可靠的代码部分,但无济于事。

我用你的 Application.cfm 页面做了测试。正如我在上面的评论中所说,您的会话会针对每个请求重新启动。 (我的意思是您的 CFID 和 CFToken 值会针对每个请求进行更改)。

我检查了你的代码流。您在这里使用会话值重置 CFID 和 CFToken cookie。

<cfif structKeyExists(session,"cfid")>
    <cfcookie name="cfid" value="#session.cfid#" expires="NOW">
    <cfcookie name="cftoken" value="#session.cftoken#" expires="NOW">
</cfif>

在每次请求时,都会执行 Application.cfm 页面。那时,上述条件 structKeyExists(session,"cfid") returns 对于每个请求都成立。所以每个请求 运行 都是 <cfcookie> 代码。您已将 cookie 设置为过期 "Now",这意味着它们会立即过期。这样您的会话就被认为是一个新会话。这是您的应用程序中的问题。

根据 the docs

The cookie expires when the user closes the browser, that is, the cookie is "session only".

所以请检查您的上述情况。我不确定您为什么要立即使 cookie 过期。可能你的业务逻辑是这样的,但是代码逻辑不对。

因此请根据您的业务需求更改此逻辑。请删除该代码并重新启动您的应用程序,然后您将只为每个请求获得一个 CFID 和 CFToken,直到会话过期。

下图我已经运行应用程序设置CFCookie值。每个请求都被认为是不同的 CFID 和 CFToken 值。您可以在下面看到 CFID 不同,例如 2106,2107,2108

如果我删除带有 cookie 值的条件,则它被视为只有一个会话。 CFID 保持为 2109,直到会话到期。

所以请更正您的条件和 CFCookie 功能。这就是问题的原因。