Yesterday, as I was working on my Scotch On The Rocks (SOTR) ColdFusion Framework presentation, I discovered a huge error in my understanding of the way in which cookies can be set in ColdFusion. For years, I thought the difference between the CFCookie tag and the Cookie scope was that only the CFCookie tag caused the given cookie to be sent to the client where as the cookie scope was just a regular struct. Meaning, you could use the cookie scope to store arbitrary values; but, if you wanted to send cookies to the client, you needed to do so with the CFCookie tag.
I don't know when or how I formulated this belief but, as I found out yesterday, it happens to be completely wrong. As it turns out, both the CFCookie tag and the Cookie scope send cookies to the client. The only real difference between them is that CFCookie gives you more control over how the cookies are sent to the client. When you use the Cookie scope directly to set a cookie, it creates a session cookie (which expires when the browser is closed) for the current domain. CFCookie, on the other hand, gives you the ability to control all aspects of the cookie including its domain, pathing, and secure page usage.
To demonstrate this, I set up this snippet of code:
<!--- Set a cookie with CFCookie. --->
<!--- Set a cookie directly with COOKIE scope. --->
<cfset cookie.setWithCookie = true />
As you can see, I am setting cookies using both the CFCookie tag as well as the raw Cookie scope. When we run this code, we see the following page response activity in Firebug:
As you can see, both approaches sent cookie headers to the client; the only difference was that the cookie set via the Cookie scope has no expiration date (session cookie).
In order to do this, the Cookie scope has to be special; it doesn't constantly re-send all the available cookies - it only sends the cookies that were created in the current request. As such, I figure that the cookie scope must have some sort of implicit setter methods that "listen" for property updates. And, when they detect that the cookie scope has been programmatically mutated, it knows to add additional Headers to the response. Out of curiosity, I dump'ed out the underlying Java class and got this:
Clearly, the cookie scope is not a standard ColdFusion struct (coldfusion.runtime.Struct). This must be how it knows to set additional response headers as the name-value cookie pairs are set. Luckily, as my pervious view on cookies was "stricter" than necessary, it never caused unexpected behaviors. But, now that I know that I don't need to use the CFCookie tag all the time, direct use of the cookie scope will be a very nice and easy way to create session cookies.
Want to use code from this post? Check out the license.