更改 CF9 中的 OnRequestEnd 行为(是 ColdFusion 9 错误 - 无法在 OnRequestEnd 中引用请求变量)
Posted
技术标签:
【中文标题】更改 CF9 中的 OnRequestEnd 行为(是 ColdFusion 9 错误 - 无法在 OnRequestEnd 中引用请求变量)【英文标题】:Change to OnRequestEnd behavior in CF9 (was ColdFusion 9 Bug - Can't Reference a Request Variable in OnRequestEnd) 【发布时间】:2012-04-21 16:32:31 【问题描述】:这是一个奇怪的问题。我没有在 Google 上找到任何有关这方面的信息,所以我想知道你们中是否有人以前见过这个?
我在请求范围内有一个 CFC,然后在 onRequestEnd 事件中,我将该 CFC 从请求范围中取出并用它做一些请求结束的事情。问题是我无法在我的 onRequestEnd 事件中引用该变量,因为它会产生一个错误,指出它没有在范围内定义......但这就是它变得非常奇怪的地方以及为什么我知道这是一个错误(它不仅仅是一个怀疑)...如果我 DUMP 变量,cfdump 标记成功显示 CFC 及其所有内容...然后产生相同的“在范围内未定义”错误。这是一个屏幕截图。
所以……有人见过这个吗?因为我完全被难住了。我已经安装了 9.0.1 更新程序和两个累积修补程序。
附言是的,我知道它说的是 OnRequestEnd.cfm,但这实际上是在 Application.cfc onRequestEnd 方法中——它是最初可追溯到 CF5 的框架的遗留物,随它去吧。 ;P
编辑:好的,它变得更奇怪了...我尝试使用 evaluate() 将其设置为局部变量,这显然有效,因为然后我转储了局部变量。转储仍然有效,即使它位于第 2 行 AFTER 发生错误的行?!!
编辑 2:编辑:这是 Application.cfc 中的代码,其中包含发生错误的文件:
<cffunction name="onRequestEnd" access="public" output="true">
<cfinclude template="OnRequestEnd.cfm">
</cffunction>
这似乎与方法和包含文件的组合有关。
如果我像这样执行 onRequestStart 中的方法,它仍然失败:
<cffunction name="onRequestStart" access="public" output="true">
<cfset onRequestEnd() />
</cffunction>
但如果我像这样将文件包含在 onRequestStart 中,它可以正常工作。
<cffunction name="onRequestStart" access="public" output="true">
<cfinclude template="OnRequestEnd.cfm">
</cffunction>
但是!显然还有更多,因为我无法创建一个简单的测试用例。如果我创建一个包含非常简单的 application.cfc 的新项目并复制所有这些细节,它就可以正常工作。因此,除了方法名和文件名之外,框架中还有其他东西对其做出了贡献。
而且文件名似乎并没有真正起作用,因为如果我像这样更改文件名,它仍然失败:
<cffunction name="onRequestEnd" access="public" output="true">
<cfinclude template="reqend.cfm">
</cffunction>
编辑 3:好的,它与文件无关......它确实如此,但与文件名无关......在 onRequestEnd.cfm 的底部是这段代码
<!--- this seems to help resolve a leaky-memory issue in CF/JRun --->
<cfset structClear(variables) />
<cfset structClear(request) />
<cfabort />
如果我注释掉那些 StructClear 语句,那么错误就会消失,它告诉我它正在执行 OnRequestEnd.cfm 两次......我认为这意味着 CF9 改变了 CFABORT 标记的行为,它现在执行使用标签时的 onRequestEnd 事件...在以前的版本中没有 cf...
我没有找到这方面的文档,但我确实找到了这个 blog from Ben Nadel 关于 CFLOCATION 标签的这种行为,所以它似乎更普遍地是关于 onRequestEnd 事件。现在似乎在 CF9 中,无论页面如何完成执行,onRequestEnd 事件都会在最后执行......这是对所有以前版本的更改,因此它与我创建的代码混在一起,以便实际导致这种情况发生在以前的版本上。由于我导致执行 onRequestEnd 然后提前中止页面,CF 现在执行 onRequestEnd,中止,然后由于中止再次执行 onRequestEnd。
幸运的是,模板顶部的这段相当简单的代码似乎解决了这个问题:
<cfif structIsEmpty(request)>
<cfexit method="exittemplate" />
</cfif>
【问题讨论】:
如果你从另一个函数调用 OnRequestEnd,可能是 OnRequestStart,你会得到预期的结果还是同样的问题? 是的,这是个好问题。这似乎与文件和Application.cfc中的onRequestEnd方法的组合有关。如果我从 onRequestStart 内部调用该函数,我仍然会收到错误,但如果我注释掉 onRequestEnd 方法的内容并将相同的 cfinclude 放在 onRequestStart 方法的末尾,那么它不会抛出错误。所以这是新信息——我们越来越近了!谢谢,丹! 帮我一个忙?将代码放入 onRequestEnd() 事件处理程序,并重命名 OnRequestEnd.cfm(因此它不会被 CF 识别为重要文件)。然后在转储周围放置一个 try/catch,并在 catch 中转储出请求范围的 structKeyArray()。发布它的屏幕截图。我对此没有依据,但是让 onRequestEnd() 处理程序调用 OnRequestEnd.cfm 处理程序似乎可能会导致问题(即:如果有一个奇怪的 CF 错误)。如果您有一个 Application.cfm 文件,也可以对 Application.cfm / onRequestStart() 执行相同的操作。 谢谢,亚当!在进行您建议的此测试的过程中,我发现了问题......结果不是我们中的任何人都在想什么,它是由我没有看到记录的 CF9 中 onRequestEnd 行为的更改引起的,但是本纳德在博客中提到。我将用答案更新这个问题。我想知道我现在是否应该删除这个问题? 很高兴您的问题得到解决。我会把这个问题留在这里,因为它是重要的信息。只需发布一个答案,我想就这样标记它。<cfabort>
的错误(由 Adobe 在 CF9.0.1 中设计引入)已在 CF10 中修复,顺便说一句。
【参考方案1】:
我决定将这个问题留在这里(而不是删除它),因为它可能会帮助其他一些人,尽管我在使用某些 cmets 时找到了问题的根源和解决方法,但这并不是我们的想法. Ben Nadel 也是posted a blog about the change to CFABORT 不久前......亚当卡梅隆告诉我,虽然这个变化是在 CF9 中设计添加的(显然没有警告任何人,因为我在 LiveDocs 中没有看到任何提及并添加了 2 cmets ),然后在(尚未发布?)CF10 中将其删除。我认为亚当可能处于测试阶段,我不确定。
【讨论】:
这是一个公开测试版,伙计。任何人都可以拿到 CF10 并试一试。以上是关于更改 CF9 中的 OnRequestEnd 行为(是 ColdFusion 9 错误 - 无法在 OnRequestEnd 中引用请求变量)的主要内容,如果未能解决你的问题,请参考以下文章
Win10 UWP系列:关于错误 0x80073CF9及一个小bug的解决
本地主机上 ColdFusion 9 和 ColdBox 中的 NullPointerExceptions