在两个页面之间丢失会话变量
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.user
和 session.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 功能。这就是问题的原因。
这很奇怪。我最近将该站点移动到 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.user
和 session.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 功能。这就是问题的原因。