The other day, I had a situation where a user had to hit a page where some processing would be triggered. The user was then immediately forwarded onto another page after the processing took place. The processing that took place did not take long, but it was not mission critical so I wanted to have the user forwarded before it was done completing (as they had no need to wait around). Normally, this is the kind of thing that I would perform using CFThread; but, since I was on a ColdFusion 7 box, I had to go another route.
I knew that CFLocation immediately aborts the current page request and forwards the user; but, I figured I would set up a base test just to make sure. I coded up a quick example, logging break points on the first page and the target page. Here is my first landing page:
<!--- Log pre-CFLocation value. ---> <cfset LogMessage( "Pre-CFLocation" ) /> <!--- Redirect user to next page. ---> <cflocation url="page2.cfm" addtoken="false" /> <!--- Log post-CFLocation value. ---> <cfset LogMessage( "Post-CFLocation" ) />
As you can see, it logs a value, CFLocation's the user to the next page, then tries to log a second value. The next page is small and simply logs a test value:
<!--- Log landing page value. ---> <cfset LogMessage( "Target Page" ) /> <p> Target Page </p>
When I run the above landing page and get forwarded to my target page, the log file has the following:
As you can see, the "Post-CFLocation" value never got logged. This is expected as the CFLocation aborted the current page request.
Now, to get around this, I have replaced the CFLocation tag with two CFHeader tags. The CFLocation tag is ultimately just setting the same header values; however, by doing this manually, we can get the same effect without having ColdFusion abort the current page request:
<!--- Log pre-CFLocation value. ---> <cfset LogMessage( "Pre-CFLocation" ) /> <!--- Tell the client that it will have to redirect. ---> <cfheader statuscode="302" statustext="Found" /> <!--- Redirect user to next page. ---> <cfheader name="location" value="page2.cfm" /> <!--- Flush header values to client. ---> <cfflush /> <!--- Log post-CFLocation value. ---> <cfset LogMessage( "Post-CFLocation" ) />
As you can see, we set the response status code and target location. The trick is then to call CFFlush directly afterwards. This immediately flushes the header values to the client (browser) which causes the redirect on the user's end. But, from ColdFusion's stand point, all we've done is committed the response so it keeps on processing the page. And, when we check out the log file, we can see that the post-CFLocation value is executed:
I don't think this is a solution that is all that critical; but, if you ever come to a scenario where you need an intermediary processing page, you can forward the user immediately with this technique without halting the processing of the current ColdFusion template.
Want to use code from this post? Check out the license.