ColdFusion Muse

Client Side and Server Side Validation - a case for both

When it comes to form elements, which kind of validation is appropriate? The new CFFORM with the flash format comes with very nice client side validation with highlights and feedback. Is that enough? Should you validate on the client using JavaScript or should you just stick with server side validation? In my opinion you should do both - but if you have to cut corners, make sure and validate on the server. Note, by validation I'm referring to checking values of a form for the correct type or requirements. For example, you might want to make sure an Social Security Number is 9 digits, or a phone number is 10 digits, or that an email address has been filled in and is the correct format. You get the idea. Here are the pros and cons of both approaches.

lient Side Validation

Validating on the client using JavaScript has the following items in its favor.

  • Immediate Feedback - The user sees the error right away and can correct it before he or she submits the request.
  • Behavioral Interactivity - You can create a "responsiveness" to your form that mimics a wizard or "steps" and gives the user the sense of progression. This is especially true of Flash Forms where the Tabbed or paned interface gives a nice "step through" type approach.
  • Maximize Performance - This is a great reason to use flash forms. Since most requests from a form hit the database in some fashion, validating on the client reduces database and web server traffic by intercepting requests before they reach the server. On a busy server this can be very helpful. In addition, the user doesn't have to wait through the page refresh to see the error and correct it.

It's not all a bed a of roses however. Client-side validation has some minuses too.

  • Browser Compatibility Issues - On a very busy public site you may have to "work around" browsers you plan to support. Not all of them will handle your nifty validation routine correctly. While it's nice to say "most people are on browser nnn, you may not be in a position to thumb your nose at the minority still using browser xxx. You'll note I'm carefully not taking any sides here (ha). For example, if you are doing a craft site your target audience may be little blue haired grandmothers. If your code generates JavaScript errors on Netscape 3.01 (just an example!) you might expect someone (probably a grandson or granddaughter) is going to be cursing you and ruing the day your were born because he or she is going to spend 2 hours that day on the phone with Grandma. Sometimes it is safe to ignore older browsers.
  • Security Settings - Some folks turn off scripting because they see it as a security risk. For these folks client side validation will simply not work.
  • Easily Thwarted - This is not a reason to not use Javascript validation. It's just something to keep in mind. In most cases getting around validation routines is pretty simple. If someone has malicious intent your client-side validation will not keep them from submitting false data to the server. JavaScript validation should not be the sole validation you use for this reason. It's great for enhancing the user experience and lousy for ensuring that no bad data is ever submitted.

Server Side Validation

You should always validate any fields with requirements on the server. If it's supposed to be a date - make sure it is a date - even if it's passed from your cool little widget as a hidden field. If it is supposed to be a number, make sure it is a number. If it is supposed to be n characters long, make sure it's n characters long. Here are some of the bad validation routines I've seen on the server.

Checking Required Without Trimming - this is an egregious error. Let's say you have a field that is required. Your validation routine makes sure that the user has filled something in before proceeding. Here is what I often see in this case:

<cfif form.fieldname IS "">
   <cfset err = "the field ""fieldname"" is required">
</cfif>
What's wrong with that? It can be easily thwarted - even accidentally thwarted - by a space. If the user submits a space then "form.fieldname" Is NOT equal to "", even though in your mind it should be, right? Make sure that you checked the "trimmed" value of any required form element.
<cfif Trim(form.fieldname) IS "">
   <cfset err = "the field ""fieldname"" is required">
</cfif>
Or better yet write a function with a descriptive name to call - an "is" function. I like "isEmpty()"
<cfscript>
   function isEmpty(str) {
      if(NOT len(trim(str)))
         return true;
      else
         return false;
      }
</cfscript>
<!--- To use it --->
<cfif isEmpty(form.fieldname)>
   <cfset err = "the field ""fieldname"" is required">
</cfif>
I like how readable the "is" syntax is - and how familiar (isNumeric(), isDefined(), isEmpty()).

Bad Dates - no I'm not talking about last evening. I'm talking about not being careful with the date values that are submitted. One thing that's often forgotten is validating for range. Can someone submit a ridiculous date to your form? Chances are that CF will say "yep, it's date all right", but it will be badly out of range for what is required. For example, if you are collecting date of birth, can someone submit a date of birth that is in future? Also, since most form values are sent to the database, it is always wise to study up on the date "types" that exist on your RDBMS. For example, if you are using MS SQL's smallDateTime data type, you should be aware that the "minimum" date it can hadle is Jan 1, 1753. If need dates before that - you should choose a different data type.

Email Address Validation - it's not "trivial" to check and see if an email exists by querying an exchanger. If your requirements call for that, then it can be done (to a point), but it is not trivial, nor is it 100% reliable (as email "standards" are something of an oxymoron). However, there is NO reason not to validate an email address for format. There are numerous functions that do exactly that. They make sure there is a string followed by an "at" sign ( @ ) followed by 2 strings separated by a dot with the last string being one of the root domains (.com, .net, .org, .gov, .biz etc). That's the least you can do. It's also possible to see if a domain exists - and it is pretty trivial to do that on a CFMX server, though it may be something of a performance drain if you are doing it constantly, because it uses Java networking classes. Cflib.org has this excellent UDF that will handle it for you.

Database Scrubbing - probaly 90% of what is submitted via forms goes into a database somewhere, yet it surprising how often form variables are passed "as is" into a CFQUERY tag. There are lots of obvious reasons to use CFQUERYPARAM tag, but preventing malicious SQL injection attacks is perhaps the most important - especially when handling form data.

Hey - if you have a tip for server side validation that you want to add to this post - please do!

Comments
Dan G. Switzer, II's Gravatar Mark,

You're correct in stating Server Side Validation is the most important. No form should be written that doesn't at least do the most rudimentary form of server side validation.

However, as you stated client-side validation plays a very important role to--for all the reason you wrote. While the CFFORM improvements in CFMX7 are great, there are still some areas where it's lacking and not everyone has access to CFMX7.

For those of you looking to implement client-side validation and interaction to your forms, no need to worry about cross-browser compliancy, just use qForms (http://www.pengoworks.com/qforms/).

With very few lines of code, you can do some tremendously neat things with your HTML forms.

For live examples, see:
http://www.pengoworks.com/qforms/docs/examples/" target="_blank">http://www.pengoworks.com/qforms/docs/examples/
http://www.pengoworks.com/qforms/v2/demo/" target="_blank">http://www.pengoworks.com/qforms/v2/demo/
# Posted By Dan G. Switzer, II | 7/6/05 1:27 PM
mkruger's Gravatar Dan - yes of course... I'm sorry. I should have mentioned your excellent qForms product - even for those who DO use CFMX 7. I have many developer friends who swear by it.
# Posted By mkruger | 7/6/05 1:53 PM
O?uz Demirkap?'s Gravatar and we use also Ajax for server side checks. As an example: while registering for our website our Ajax code check whether entered e-mail address has already been in database or not. And than show error msg directly as client side action.

It is a really great option to check availibility etc.
# Posted By O?uz Demirkap? | 7/6/05 6:13 PM
mkruger's Gravatar I LOVE that idea - very cool. However, again, it coule be pretty easily circumvented right - it would suffer from the same limitations/liabilities as the Javascript method. Still - a great user experience I would think. I'll have to try it.
# Posted By mkruger | 7/7/05 7:33 AM
Oguz Demirkapi's Gravatar http://cftr.net/cf10/index.cfm?eylem=kayit

this is a resgistration form for CF's 10th year celebration in Turkey.

Just try out to enter oguz@cftr.net email address into email field at bottom.

:)
# Posted By Oguz Demirkapi | 7/7/05 4:08 PM
barry.b's Gravatar >> and we use also Ajax for server side checks

as do we, although it's still worth remembering that this is still before the form has been submitted (unless you're packaging all the data in that AJAX call..).

The point there is that server-side validation is the last line of defence.

Exellent post, Mark. It's worth remembering (for those new to the idea) that this "validation idea" is NOT hard work, if you build it in as you go. An ounce of prevention, so to speak...

I hope my former students read it (and take notice - they got sick of me saying the same)

good on yer
# Posted By barry.b | 7/7/05 5:59 PM
barry.b's Gravatar I should have added that, we see client side validation as merely a convieniance for the user in using the UI - reduce the chance of them being cheesed off if something is wrong. How many times have people submitted a form and it comes back with big red *** on incorrect/missing form values?

Also client-side validation for us means "micro forms logic" (if this checkbox is ticked then make sure that textbox has a value, etc).

We're working on something related at the moment - disabling fields/whole records within the UI if someone else has those values out for editing...
...and on a disconnected client, it's not for the feint hearted...
# Posted By barry.b | 7/7/05 6:09 PM
mkruger's Gravatar Barry - thanks for the kind words. I like the "micro forms logic" phrase. I recently did an interface with record locking like you are indicating. The Application.cfc file in CFMX 7 made clean up on locking and sessions much easier than in the past.
# Posted By mkruger | 7/8/05 8:49 AM
Dan G. Switzer, II's Gravatar Oguz & Barry's talks got me wondering how easy it would be to integrate AJAX-type calls with qForms v2. I blogged about the experience:

http://blog.pengoworks.com/blogger/index.cfm?actio...

Turns out it's pretty painless!
# Posted By Dan G. Switzer, II | 7/8/05 4:42 PM
abhiram's Gravatar HI,

I need a rough algorithm/pseudocode for implementing the azax for server side validation of "date". could you please guide me in this aspect.

Thanks,
Abhiram
# Posted By abhiram | 7/14/08 1:38 AM
Bill's Gravatar I have a situation I have to validate server first and then client side validation, it is all been call from onChange event. Is there anyway that I can control the sequence, so do server first then client side? Wait for the server done then client validation?

Thanks,
Bill
# Posted By Bill | 3/8/10 5:04 PM



Blog provided and hosted by CF Webtools. Blog Sofware by Ray Camden.