我在两台服务器上使用ColdFusion 8,两者都具有完全相同的ColdFusion版本和相同的设置。
我们正在CFC中创建一个结构,并使用toScript()函数将其传递给浏览器。网页上生成的JavaScript如下所示:
TrackingInfo = new Object();
TrackingInfo["child_catalog_id"] = "";
TrackingInfo["ipaddress"] = "63.123.41.14";
TrackingInfo["parent_catalog_id"] = 1642;
TrackingInfo["session_id"] = 30000390;
TrackingInfo["referral"] = "";
TrackingInfo["useragent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) G ecko/20100101 Firefox/10.0.2";
TrackingInfo["querystring"] = "";
稍后在页面中,在JavaScript中,我们将TrackingInfo结构(ABOVE)传递给相同的CFC - 但是使用CFAJAXPROXY这是一个不同的函数:
var jro = new JS_SessionTracking();
jro.InsertSessionTrackingFunction(TrackingInfo);
在CFC中,InsertSessionTrackingFunction函数接受结构并将其输入数据库,
<!--- INSERT SESSION TRACKING FUNCTION --->
<cffunction name="InsertSessionTrackingFunction" access="remote">
<cfargument name="TrackingInfo" required="true">
<cfset LOCAL.TrackingInfo = ARGUMENTS.TrackingInfo>
// DATABASE STUFF HAPPENS HERE
<cfreturn true>
</cffunction>
在我们的开发和舞台网站中,这可以完美运行,在许多机器和许多浏览器中进行测试。它按设计和期望工作。
当我们将代码移动到生产时,它的每个方面都可以使用,最后一个函数(InsertSessionTrackingFunction)除外。我们的服务器拒绝处理从网页传递给CFC的JavaScript。 Firebug显示没有错误。不返回真实值。
什么可能导致CFC不喜欢在LIVE设置中传递给它的结构,但在开发设置中工作得很好?
另外,我尝试使用ColdFusion函数serializeJSON()在传递页面之前格式化结构。它输出到这样的页面:
LOCAL.TrackingInfo = serializeJSON(LOCAL.TrackingInfo); // serialize the structure
TrackingInfo = "{\"CHILD_CATALOG_ID\":\"\",\"IPADDRESS\":\"63.173.41.14\",\"PARENT_CATALOG_ID\":1642,\"SESSION_ID\":30000390,\"REFERRAL\":\"\",\"USERAGENT\":\"Mozilla\\/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko\\/20100101 Firefox\\/10.0.2\",\"QUERYSTRING\":\"\"}";
我将结构传递给函数并使用deserializeJSON函数来解析它:
<cfset LOCAL.TrackingInfo = deserializeJSON(LOCAL.TrackingInfo)>
尽管如此,此功能在开发和暂存中仍能正常工作,但在生产中失败。
请告诉我为什么会发生这种情况以及如何纠正这个问题。
更新
我接受了Jake Feasel的建议并在每个函数的头部添加了<cfset var LOCAL = {}>
,以确保值不会浮动。虽然它似乎是CF8的好习惯,但这并没有解决问题。
以下代码在生产和我们的实时环境中运行良好。无需更改CFC即可完成此项工作。 ColdFusion根本不允许将该结构传递到该服务器上的函数中。
<script>
<cfoutput>
#toscript(TrackingInfo.SID, "SID")#
#toscript(TrackingInfo.parent_catalog_id, "Parent")#
#toscript(TrackingInfo.child_catalog_id, "Child")#
</cfoutput>
// CREATE JAVASCRIPT OBJECT
var jro = new JS_SessionTracking();
jro.InsertSessionTrackingFunction(SID,Parent,Child);
</script>
答案 0 :(得分:2)
常见问题排查地点以查找测试与产品差异:
但是,现在我们已经在特定情况下消除了那些可能的问题来源....
您说您的所有CF版本都是相同的,并且您使用的是CF 8.但是,您尝试使用的“本地”范围是在CF 9中引入的:
http://forta.com/blog/index.cfm/2009/6/21/The-New-ColdFusion-LOCAL-Scope
由于(从您的评论中)这是您看到错误的地方,我怀疑这是问题所在。
<强>更新强>
有一点值得一提的是在CF8中使用LOCAL - 使用它不会引发错误,但很可能会出现意外行为(可能就像你在这里看到的那样)。
<cffunction name="foo">
<cfset local.bar = "Hello World">
<cfreturn local.bar>
</cffunction>
我在CF8中测试了上面的例子,它“有效” - 它不会抛出错误。但是,它将要做的是在请求或组件的变量范围中创建一个名为“local”的新结构(取决于函数所在的位置)。然后,它将在该上下文中全局可用(如果您正在缓存CFC实例,则可能是持久的)。如果这是CFC的共享缓存实例,则很可能如果您同时从多个客户端访问它(如果函数长时间运行,则特别明显),那么您将在每次请求时覆盖该局部变量。 这只是在开发或登台时不会显而易见的问题,因为一次访问该网站的用户较少。此外,如果您在不同的功能中使用相同的名称,一个人可能会与你正在运行的实例发生冲突,导致谁知道出现了什么样的问题。
最好的选择是通过添加一行来更新您的功能:
<cffunction name="InsertSessionTrackingFunction" access="remote">
<cfargument name="TrackingInfo" required="true">
<cfset var LOCAL = {}>
<cfset LOCAL.TrackingInfo = ARGUMENTS.TrackingInfo>
// DATABASE STUFF HAPPENS HERE
<cfreturn true>
</cffunction>
这会明确地将您的本地范围限制为您的功能。
你可能没有在firebug中看到错误,因为你可能有一些全局错误处理程序可以抑制CF错误,可能只在生产时设置为禁止。
答案 1 :(得分:1)
CF管理员中有一个名为“Prefix serialized JSON with”的设置,默认为//
。如果您的测试和生产系统的设置不同,则可能会导致问题。