自从我从 CF9 升级到 CF10 以来,我一直在与 cflocation 的错误作斗争。 我已经做过很多次了,但总是放弃,但今天它终于让我很恼火,是时候解决问题了(我希望)。
首先,很抱歉,因为我试图编写一个简单的测试用例来重现这个问题,但到目前为止,我无法在原始代码之外重现它。
我有一个多步骤导入过程,应该在一夜之间运行。 该过程由大约 10 个链接在一起的文件组成。 通过计划任务调用进程时,还会传递 URL 参数(计划任务)。 如果该参数不存在,则在每个步骤结束时,它将停止并等待用户单击指向下一步的链接。 如果参数确实存在,则使用 cflocation 移动到下一步。
在所有步骤中,第二个是最复杂和最耗时的(来自多个 Web 服务请求的数据,然后需要加入、清理和插入到数据库中)。 这是迁移到CF10后出现问题的第二步。 该页面似乎工作正常,因为它到达了 cflocation 标签所在的页面底部,但它永远不会触发 cflocation。 我添加了一个 cfmail 标签,以便在调用 cflocation 时给我发送电子邮件,该标签始终被发送,但 cflocation 再次不会触发。
它不能比以下更基本:
<cfif scheduledtask EQ "true">
<cfmail from="xxxxx” to="xxxx” subject="About to call duplicate" type="text/html">
<p>calling duplicate check - scheduledtask</p>
</cfmail>
<cflocation url="importDupCheck.cfm?scheduledtask=true" addtoken="false">
</cfif>
我知道 cfflush 和 cflocation 存在问题,我已经检查过了。
作为测试,我尝试将上述逻辑向上移动到Web服务检索所有数据之后,但在处理之前,这次cflocation起作用了。 我想这可能是一个超时问题,即使允许页面完全加载,计划的任务引擎也放弃了等待。 我尝试通过拥有一个具有以下基本文件来测试这一点:
<cfset sleep(240000)>
* 4 minutes
在它调用CFlocation之前,但它工作正常。
该过程中的其他步骤正在按预期使用 cflocation 工作,只是不是这个步骤。 所有这些代码在 CF9 下运行良好,只是在 CF10 下失败。
有没有人对我应该在哪里寻找有一些指示?
问候马克
* 更新 *所以我现在已经弄清楚了如何在几行代码中轻松重现它。 事实证明,它与计划任务无关。
索引.cfm
<h1>Testing cflocation</h1>
<cfloop index="i" from="1" to="7000" ><!--- For me it stops working once the loop goes beyond 6808 rows --->
row <cfoutput>#i#</cfoutput>: abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789<br/>
</cfloop>
<p>Now loading resultpage via cflocation</p>
<cflocation url="resultpage.cfm" addtoken="false">
结果页.cfm
<h1>Made it!</h1>
<p>Reload the <a href="index.cfm">first page</a></p>
在我的测试中,我发现如果我循环 6808 次它可以工作,但 6809 次失败。 有 7000 条记录,我们只谈论一个 36 KB 的文件......为什么只在 CF10 中失败?
我应该注意的最后一件事,以防它产生影响 - 我所做的一切都是通过https完成的。
我解决了
在 CF 管理器中
最大输出缓冲区大小 1024
之后将发生刷新,这将停止 cflocation 工作。
增加它,它有效。
怕我不知道为什么你的代码不起作用。猜测,这取决于ColdFusion 10对计划任务引擎的替换,并且它不喜欢一些变幻莫测的客户端重定向。
但是,也许无论如何您都可以绕过这种情况。
ColdFusion 10 的调度程序具有链接任务的概念,因此当一个任务完成时,另一个任务被启动。您可以想象修改您的调度程序以利用它吗?
我有一个类似的问题,但我在 cfscript 中使用了 location() 函数。但我怀疑同样的原则也适用。
在 location() 函数之前,我们调用的函数没有包装在 <cfsilent>
标签中。结果,函数的每一行,包括循环,都被输出为 HTML 的空行。当我查看源代码时,有超过 20,000 行空的 HTML 代码。这可能足以达到 1024 kb 缓冲区限制并触发中止重定向的刷新。
通过向自定义函数添加<cfsilent>
标签,我将 HTML 的空行数减少到 39 行,现在 location() 函数按预期工作。
要确定这是否是您遇到的问题,请添加中止;(或 <cfabort>
) 就在 location() 前面,然后查看生成的(大概是空的)页面的源代码。
您是否尝试过在CFLOCATION
后添加CFABORT
?这就是我一直在做的事情 - 因为不应该执行CFLOCATION
之后的代码。
如果您检查来自服务器的响应(使用 Charles 代理、Fiddler 或类似的东西),您可能会在 HTML/JS 中找到阻止重定向的内容。