Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at CFinNC 2009 (Raleigh, North Carolina) with: Yancy Wharton
Ben Nadel at CFinNC 2009 (Raleigh, North Carolina) with: Yancy Wharton@ywharton )

Using structDelete() With Cookies Does Not Alter Cookie Scope In ColdFusion

By Ben Nadel on
Tags: ColdFusion

For years, I've known that using structDelete() with the Cookie scope, in ColdFusion, will send HTTP response headers to expire the given cookie in the user's browser. However, I don't think I ever thought about what this action was actually doing to the Cookie scope itself. Until yesterday, when I was baffled by the existence of a cookie on the server. After a little investigation, it looks like calling structDelete() on the Cookie scope doesn't actually alter the Cookie scope.

To see this in action, I've put together a small demo that creates a cookie, if it doesn't exist, and then tries to delete it and subsequently check to see if it exists:

  • <cfscript>
  •  
  • // If the cookie doesn't exist, create it.
  • if ( ! structKeyExists( cookie, "hello" ) ) {
  •  
  • cfcookie(
  • name = "hello",
  • value = "world",
  • preserveCase = true
  • );
  •  
  • }
  •  
  • // Delete the cookie from the SPECIAL cookie scope.
  • // --
  • // NOTE: Behind these scenes this is actually sending a "Set-Cookie" header with
  • // an "Expires" date in the past so that the browser knows to flush the cookie
  • // from the local cache.
  • structDelete( cookie, "hello" );
  •  
  • // Check to see if structDelete() actually deleted the cookie.
  • writeOutput( "Cookie exists after structDelete() operation: " );
  • writeOutput( structKeyExists( cookie, "hello" ) );
  •  
  • </cfscript>

As you can see, I'm using the structDelete() to try to delete the cookie and then using structKeyExists() to see if the cookie scope has been altered. When we run this code, we get the following output:

Cookie exists after structDelete() operation: YES

As you can see, even after the structDelete() call, the cookie still exists in the cookie scope. Considering that the cookie scope acts like a standard scope, this behavior tripped me up a little bit.

Now, if you look in the CFCookie documentation, you will see that it does mention that setting an expires="now" value with the CFCookie tag will set the expiration but not alter the cookie scope:

Expires: now: deletes cookie from client cookie.txt file (but does not delete the corresponding variable the Cookie scope of the active page).

Of course, I'm not setting the "expires" value using the CFCookie tag - I'm deleting the cookie from the scope. But, behind the scenes this seems to be doing (almost) the same thing.

For posterity, I ran the same experiment with the CFCookie tag:

  • <cfscript>
  •  
  • // If the cookie doesn't exist, create it.
  • if ( ! structKeyExists( cookie, "hello" ) ) {
  •  
  • cfcookie(
  • name = "hello",
  • value = "world",
  • preserveCase = true
  • );
  •  
  • }
  •  
  • // Expire the cookie immediately.
  • // --
  • // NOTE: Behind these scenes this is actually sending a "Set-Cookie" header with
  • // a "Max-Age" value of zero so that the browser knows to flush the cookie from
  • // the local cache.
  • cfcookie(
  • name = "hello",
  • expires = "now",
  • preserveCase = true
  • );
  •  
  • // Check to see if cfcookie() actually deleted the cookie.
  • writeOutput( "Cookie exists after cfcookie(expires) operation: " );
  • writeOutput( structKeyExists( cookie, "hello" ) );
  •  
  • </cfscript>

As you can see, rather than using structDelete(), I'm using CFCookie to set an immediate expiration. And, when we run the page, we get the same output:

Cookie exists after cfcookie(expires) operation: YES

Since I'm using the CFCookie tag, this behavior is consistent with the documentation.

In the end, I don't think this is a bug; when you call structDelete(), it's clearing doing something akin to setting "Expires" in the background. As such, it makes sense that the use of structDelete() and the use of CFCookie(expires) should result in very similar behaviors. The fact that the Cookie scope can act like a normal struct and hooks into the "expires" workflow is actually a nice-to-have feature, even if it can be a little confusing at times.




Reader Comments

@JC,

I'm not sure that you can - not within the current request. But, the structDelete() action will cause an "expires" Set-Cookie header to get be sent, which should expire the cookie in the browser. Then, the cookie should be absent from subsequent requests.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.