ASP 101 - Active Server Pages 101 - Web06
The Place ASP Developers Go!



Windows Technology Windows Technology
15 Seconds
4GuysFromRolla.com
ASP 101
ASP Wire
VB Forums
VB Wire
WinDrivers.com
internet.commerce internet.commerce
Partners & Affiliates
ASP 101 is an
internet.com site
ASP 101 is an internet.com site
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

ASP 101 News Flash ASP 101 News Flash



 Top ASP 101 Stories Top ASP 101 Stories
What is Adovbs.inc and Why Do I Need It?
An Overview of ASP.NET
Connections, Commands, And Procedures

QUICK TIP:
Use <% OPTION EXPLICIT %>
Show All Tips >>
ASP 101 RSS Feed ASP 101 Updates


An Overview of Cookie Detection in ASP (with Code!)

An Overview of Cookie Detection in ASP

(with Code!)

by John Peterson

Introduction

Detecting whether or not a visitor to your web site can accept cookies is not difficult. There are, however, a number of issues involved in the process which can cause it to get confusing. This article will explain the problems faced and address them one by one. This will result in a cookie detection script written in ASP that you can use on your own site.

The Problem

I often get asked how you can check to see if a visitor to your web site user has cookies enabled or not. It used to be because not all browsers supported them. These days, even though they are almost universally supported, there is still a stigma associated with cookies and many users go out of their way to disable them. So even if you find out that their browser can support them, it does not mean that it will accept the cookies you send. The only way to be sure cookies are available for you to use is to actually try and use them and see if they work. So that's the approach this script will take.

So... what's the big deal?

This seems pretty simple so far. I'll set a cookie and see if it exists. A simple piece of code should accomplish this.

cookie_bad.asp
<%@ Language="VBScript" %>
<%
Option Explicit
' Declare 2 variable to hold our values.
Dim strCookieValueSet
Dim strCookieValueRead
' Set two default values that are different.
strCookieValueSet  = "true"
strCookieValueRead = "false"
' Set a test cookie with a value and an expiration date.
Response.Cookies("cookie_test") = strCookieValueSet
Response.Cookies("cookie_test").Expires = Date + 1
' Read the cookie to see if it exists.
strCookieValueRead = Request.Cookies("cookie_test")
' Compare the value set and the value read back.
' If they're the same it would seem that cookies
' are actually working.
If strCookieValueSet = strCookieValueRead Then
	Response.Write "Cookies Are Supported!"
Else
	Response.Write "Cookies Are Not Supported!"
End If
' Don't be fooled... try this script with a browser
' that has cookies turned off... it still says cookies
' are enabled!  (It's really not the script's fault!)
%>

I've gotten many pieces of code that have attempted this approach and they're usually accompanied by a note asking where the typo is in the script. There's not one! Now let me explain why that doesn't work.

The web works over the HTTP protocol which is where cookies come from. A complete HTTP request consists of the browser asking for a piece of content and the server responding with the content the browser asked for. Well, along with this request and content, there is additional information sent so that both the client and the server know how to handle the content. This additional information is contained in headers that are sent along with the transmission in both directions. These headers can contain cookie information. Via these headers, the server can set cookies and according to the HTTP standards, browsers that have received a cookie from a server are supposed to send that cookie back to the server with all future requests to that same server (until the cookie reaches its expiration date and time). It is this interaction with the headers that ASP does for you when you use the Response.Cookies or Request.Cookies collections.

The problem lies in the order in which the events must occur. As I mentioned earlier, requests comes in and then the server sends a response. Well, the ASP processing happens at the server in between these two steps. As such, ASP has access to the cookies sent with the request and can set cookies to be set in the response, but it really has no idea if those cookies it just told the browser to set will ever actually be set. Those are the cookies that the above script reads back from the cookie collection right after it sets them. They haven't yet made the trip to the browser and been sent back, so there's really no way to be sure they ever will be.

Checking for a Reply

So since we can't see if a cookie has been sent back on the first request, it actually takes two requests to complete our cookie test. The first one to set the cookie during the response. The second one to see if the browser sent it back with the reply. This is all well and good, but it can be cumbersome to manage so I've tried to wrap it up into a nice little page you can add you your site and utilize just by adding a few lines to any page.

Let me outline the basic process. A request comes in to a page on your web site (cookie.asp). This page contains some code that checks for a signal that cookie detection has been done. If it finds it, it continues about its business using this information as it sees fit. If, on the other hand, it doesn't, it directs the browser to the cookie detection script (cookie_detect.asp) which determines this information and sends the browser back to the original page (cookie.asp) along with the new found knowledge of whether or not cookies are supported.

Now passing all this information around is what became the hard part in this script. I can't use sessions or cookies since they both rely on cookies! So that basically left me with the QueryString and so that's what I used.

Without any more ado... here are the two scripts involved.

cookie.asp
<%@ Language="VBScript" %>
<%
Option Explicit
' Buffering needs to be on to be able to redirect to
' the detection script if we need to.
Response.Buffer = True
Dim bCookies ' T/F indicating cookies enabled.
Dim strURL   ' URL to this page.
Dim strQS    ' QueryString of initial request.
' Read in the value of cookie enablement.
bCookies = Request.QueryString("cookies")
' Check for a value indicating cookie enablement.
Select Case LCase(bCookies)
   Case "true", "false"
      ' We got a valid response.
      bCookies = CBool(bCookies)
   Case Else
      ' We didn't get a valid response.
      ' Get the info we need to pass to our detection
      ' script so we can get back here.
      strURL = Request.ServerVariables("URL")
      strQS  = Request.QueryString
      ' Clean up trailing ? problem we ran into
      ' if there's no QS on initial request.
      If strQS <> "" Then strQS = "?" & strQS
      ' Send browser to be tested and tell the test
      ' script where to send them when they're done
      ' being tested.
      Response.Redirect "cookie_detect.asp?from=" _
         & Server.URLEncode(strURL & strQS)
End Select
' By the time we get here, we should always have a
' boolean value in bCookies indicating whether or
' not cookies are enabled.
%>
<html>
<head>
  <title>This Page Needs to Know if Cookies Work</title>
</head>
<body bgcolor="#FFFFFF">
Cookies Are Enabled: <%= bCookies %>
</body>
</html>

cookie_detect.asp
<%@ Language="VBScript" %>
<%
Option Explicit
' We need buffering to be able to redirect.
Response.Buffer = True
' Retreive our own script name for the cookie test.
Dim strThisScriptName
strThisScriptName = Request.ServerVariables("URL")
' Declare a variable to pass the referring page path
' from the set to the read and then to redirect to.
Dim strFrom
' Check if we've already set a cookie to check.
If Request.QueryString("action") <> "checkcookie" Then
   ' We haven't set the test cookie yet.
   ' Get the info from the sending script about
   ' where to send the user when we're done.  If
   ' we don't find anything we try and get it
   ' ourselves or if that fails just send them to
   ' the root of the site so they end up somewhere.
   strFrom = Request.QueryString("from")
   If strFrom = "" Then
      strFrom = Request.ServerVariables("HTTP_REFERER")
   End If
   If strFrom = "" Then
      strFrom = "/"
   End If
   ' Set a test cookie with a value and an expiration date.
   Response.Cookies("cookie_test") = "true"
   Response.Cookies("cookie_test").Expires = Date + 1
   ' This is useful if you need to remove the test
   ' cookie while you are testing.
   'Response.Cookies("cookie_test").Expires = Date - 2
   ' Send the browser to the read back phase of the test.
   ' Notice the action attribute we check for above.
   ' We also continue to pass the from attribute.
   Response.Redirect strThisScriptName & "?from=" _
      & Server.URLEncode(strFrom) & "&action=checkcookie"
Else
   ' Boolean indicating cookie enablement.
   Dim bCookiesEnabled
   ' Read back our values during second request.
   bCookiesEnabled = Request.Cookies("cookie_test")
   bCookiesEnabled = (bCookiesEnabled = "true")
   ' Read in the referring script path.
   strFrom = Request.QueryString("from")
   ' Append appropriate QS character
   If InStr(1, strFrom, "?", 1) = 0 Then
      strFrom = strFrom & "?"
   Else
      strFrom = strFrom & "&"
   End If
   ' Send the browser back to the start with a QueryString
   ' variable named cookie set to either true of false.
   Response.Redirect strFrom & "cookies=" & bCookiesEnabled
End If
%>

Problems

While these scripts are relatively easy to use, please realize that any time you start doing a lot of redirects it will add to the load on your server and slow your apparent response time. Please use these files with a sense of caution and if you need to know if cookies are enabled on a lot of pages, it really does make more sense to test them once and then store this value somewhere so you don't have to keep testing the browser.

You could also run into trouble with some caching solutions. If the caching is not very smart, you could easily end up telling users who have cookies enabled that they don't and vice versa. In an attempt to keep them to the point, these scripts don't address caching, but you might need to start setting headers to stop caching of these pages if it becomes a problem for you.

Conclusion

I hope this has helped shed some light on the cookie detection problems you might have encountered or at very least made for an interesting read.

If you'd like to play with the files, I've included cookie_bad.asp, cookie.asp, and cookie_detect.asp in this zip file.


Update: Single File Cookie Detection

I recently got an email from a reader who had this to say:

Hi John,

Not sure how old the article is but I had an idea to achieve the same goal on the same page. Still requires a redirect, but because the code stops executing after the Response.Redirect line, it should reduce server load. The page name for the example below would be cookietest.asp

<%
If Request.Querystring("Check") = "" Then
	Session("cookietest") = "True"
	Response.Redirect("cookietest.asp?Check=True")
Else
	If Session("cookietest") Then
		<!-- Execute code if enabled -->
	Else
		<!-- Execute code if disabled -->
	End If
End If
%>

Just a thought. Thanks for the page!
Scott

Scott is absolutely right... you could easily do this in one page. I separated it into two to try and keep things easier to follow as to which file was doing what. You might also notice that Scott's script is 1/20th the length of mine. If you're curious as to why... the majority of the difference in length comes from the comments, filename independence, and querystring passthrough that the original script includes which Scott's doesn't. These could easily be incorporated into a one-page solution as well.

In terms of performance... Scott's script does alleviate a couple of redirects. The original script does none of the processing in the "host" page and therefore needs to "hand off" to the processing script and then "hand" the result back to the "host" page. This is where the additional redirects are incurred. While no script will work for everyone right "out of the box" (or in this case right "off the site"), the approach which will work best for you depends on your situation.

If there's enough interest, I'll be happy to write a more "useable" version. It shouldn't be all that difficult to combine aspects of both scripts into a simple include file that could easily be added to any asp page. Ideally it would do the processing on one page like Scott's script, yet include the additional features of the original.


Related Articles

Related Commercial Products

  • BrowserHawk - A browser capabilities product which includes support for detecting disabled cookies.

Home |  News |  Samples |  Articles |  Lessons |  Resources |  Forum |  Links |  Search |  Feedback

Internet.com
The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers