Solved

Simple Secure Contact Us Form Page Script

Posted on 2008-10-21
4
664 Views
Last Modified: 2013-11-19
Nearly everyone has a 'Contact Us' page on their site, right? Why is it so difficult to find a script that is simple, secure and unobtrusive (if using AJAX/JS) on the net?

I am looking for a ready to use script that displays a html form on the front end with the following inputs;

Name
Email
Subject
Message

User types in their stuff, some server side validation takes place and if it passes, an email is sent to me and a success message is displayed to the user.

Bonus if there is use of unobtrusive ajax, i.e. form validation error messages, message is sent and success statement displayed without page reload etc.

Please show me examples you know about that are simple, secure and work across browsers.  Thanks.

(site is hosted on windows server with php available)
0
Comment
Question by:thyros
4 Comments
 
LVL 8

Accepted Solution

by:
MatthiasVance earned 250 total points
ID: 22772134
I hope this helps you, I attached two files with some example code.

Kind regards,

Matthias Vance
<!-- This file is named form.php -->
<script language="JavaScript">
	var request;
	
	// This function is copied from http://cass-hacks.com/articles/code/js_url_encode_decode/
	function URLEncode(clearString) {
	  var output = '';
	  var x = 0;
	  clearString = clearString.toString();
	  var regex = /(^[a-zA-Z0-9_.]*)/;
	  while (x < clearString.length) {
		var match = regex.exec(clearString.substr(x));
		if (match != null && match.length > 1 && match[1] != '') {
			output += match[1];
		  x += match[1].length;
		} else {
		  if (clearString[x] == ' ')
			output += '+';
		  else {
			var charCode = clearString.charCodeAt(x);
			var hexVal = charCode.toString(16);
			output += '%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase();
		  }
		  x++;
		}
	  }
	  return output;
	}
 
	function checkForm() {
		// Prepare URL
		var url = "check_form.php?";
		url += "name=" + URLEncode(document.getElementById("name").value) + "&";
		url += "mail=" + URLEncode(document.getElementById("mail").value) + "&";
		url += "subject=" + URLEncode(document.getElementById("subject").value) + "&";
		url += "message=" + URLEncode(document.getElementById("message").value);
		alert(url);
		
		// Perform XmlHttpRequest
		request = null;
		if(window.XMLHttpRequest) {
			request = new XMLHttpRequest();
		} else if(window.ActiveXObject) {
			request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		if(request != null) {
			request.onreadystatechange = function() {
				if(request.readyState == 4 && request.status == 200) {
					if(request.responseText == "OK") {
						alert("Your message has been sent!"); // Inform the user
						window.location = "http://localhost/test/form/"; // Redirect
					} else {
						document.getElementById("error").innerHTML = request.responseText;
					}
				} else {
					// There was a problem retrieving the data
				}
			}
			request.open("GET", url, true);
			request.send(null);
		} else {
			// This browser doesn't support the use of XmlHttpRequest
		}
	}
</script>
<form id="form" onsubmit="return false;">
	Name:<br /><input type="text" id="name" name="name" /><br />
	E-mail:<br /><input type="text" id="mail" ame="mail" /><br />
	Subject:<br /><input type="text" id="subject" name="subject" /><br />
	Message:<br /><textarea id="message" name="message"></textarea><br />
	<input type="submit" value="Send message" onClick="checkForm()"/>
</form>
<div id="error"></div>
 
<!-- This file is named check_form.php -->
<?php
	$error = "";
	$count = 0;
 
	$name = $_GET['name'];
	if(strlen($name) > 0) {
		$count++;
	} else {
		$error .= "You must supply a name.<br>";
	}
 
	$mail = $_GET['mail'];
	if(strpos($mail, "@")) {
		$count++;
	} else {
		$error .= "You must supply a valid mail address.<br>";
	}
 
	$subject = $_GET['subject'];
	if(strlen($subject) > 0) {
		$count++;
	} else {
		$error .= "You must supply a subject.<br>";
	}
 
	$message = $_GET['message'];
	if(strlen($message) > 0) {
		if(strlen($message) < 1024) {
			$count++;
		} else {
			$error .= "Your message must not exceed 1024 characters.<br>";
		}
	} else {
		$error .= "You must supply a message.<br>";
	}
 
	if($count == 4) {
		ini_set("sendmail_from", "WebMail"); // This may be needed
		mail("yourmail@yourdomain.com", $subject, $mail . "\n\r\n\r" . $message);
		echo "OK";
	} else {
		echo $error;
	}
?>

Open in new window

0
 
LVL 7

Assisted Solution

by:tg_wilk
tg_wilk earned 250 total points
ID: 22772699
Something based on similar principles. The main differences:
- object oriented (php)
- xml http request using post rather then get method - the advantage is that some browsers (IE for example) limit the length of a get request. This doesn't happen with post data.
- more thorough check of an email address

Description:
- contact.us.class.php - main engine
- contact.us.js - client part
- load.gif - animation
- index.php and contactus_backend.php show the example implementation.
Create a folder, copy all the files and start playing around. You'd want to change the e-mail address in contactus_backend.php for starters.
<-- index.php -->
 
 <html>
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 		<script type="text/javascript" src="contact.us.js"></script>
 	</head>
 	<body>
 		<p>This is the simple contact us form. The page loaded on <?php echo date('Y-m-d H:i:s') ?> and
 		haven't reloaded since.</p>
 		<p>
 			<?php
 				include('contact.us.class.php');
 				$CU = new ContactUs('contactus_backend.php');
 				echo $CU->ContactForm();
 			?>
 		</p>
 	</body>
 </html>
 
 
 
 
<-- contactus_backend.php -->
 
<?php
include('contact.us.class.php');
 
$CU = new ContactUs("","UTF-8","email@to.send.to.com");
$CU->Process();
?>
 
 
 
<-- contact.us.class.php -->
 
<?php
class ContactUs {
	private $BackEnd;
	private $Charset;
	private $SendTo;
 
	public function __construct($BackEnd="",$Charset="UTF-8",$SendTo="your_email@yourdomain.com")
	{
		$this->BackEnd = $BackEnd;
		$this->Charset = $Charset;
		$this->SendTo = $SendTo;
	}
 
	public function ContactForm($BackEnd="")
	{
		if ($BackEnd != "") $this->BackEnd = $BackEnd;
		$result = '<div id="CUstatus"></div>
			<div id="CUdiv">
			<form name="CUform" method="POST">
			Name: <input type="text" name="CUname" value="" /><br />
			E-mail: <input type="text" name="CUemail" value="" /><br />
			Subject: <input type="text" name="CUsubject" value="" /><br />
			Message: <br /><textarea name="CUmessage"></textarea><br />
			<input type="button" name="CUsubmit" value="Submit" onclick="CUSubmit(\''.$this->BackEnd.'\');" />
		</form></div>';
		return $result;
	}
 
	public function Process()
	{
		if ($this->Validate())
		{
			header('Content-type: text/xml; charset='.$this->Charset);
			if ($this->SendContactInfo())
			{
				echo "<response>
					<status>ok</status>
				</response>";
			}
			else
			{
				echo "<response>
					<status>error</status>
					<error>There was an error while trying to send contact info. Please try again later.</error>
				</response>";
			}
		}
	}
 
	private function SendContactInfo()
	{
		$name = $_POST['name'];
		$email = $_POST['email'];
		$subject = str_replace("\n"," ",$_POST['subject']);
		$message = $_POST['message'];
 
		$charset=$this->Charset;
		$encoded_subject="=?$charset?B?".base64_encode($subject)."?=\n";
		$body = "Name: $name\nE-mail: $email\nSubject: $subject\nMessage:\n$message";
		$headers="From: ".$this->SendTo."\n"
		. "Content-Type: text/plain; charset=$charset; format=flowed\n"
		. "MIME-Version: 1.0\n"
		. "Content-Transfer-Encoding: 8bit\n"
		. "X-Mailer: PHP\n";
		//echo "here";flush();
		return mail($this->SendTo,$encoded_subject, $body,$headers);
	}
 
	private function Validate()
	{
		$name = isset($_POST['name'])?$_POST['name']:'';
		$email = isset($_POST['email'])?$_POST['email']:'';
		$subject = isset($_POST['subject'])?str_replace("\n"," ",$_POST['subject']):'';
		$message = isset($_POST['message'])?$_POST['message']:'';
 
		$error = '';
		if (strlen($name)<3) $error .= 'Name has to be at least 3 characters long. ';
		if (strlen($name)>256) $error .= 'Name has to be less then 256 characters long. ';
		if (!$this->ValidateEmail($email)) $error.= "Email $email is not valid. ";
		if (strlen($subject)<3) $error .= 'Subject has to be at least 3 characters long. ';
		if (strlen($subject)>256) $error .= 'Subject has to less then 256 characters long. ';
		if (strlen($message)<3) $error .= 'Message has to be at least 3 characters long. ';
		if (strlen($message)>2000) $error .= 'Message has to be less then 2000 characters long. ';
 
		if (!empty($error))
		{
			header('Content-type: text/xml; charset='.$this->Charset);
			echo "<response>
			<status>error</status>
			<error>$error</error>
			</response>";
			return false;
		}
		else return true;
	}
 
	private function ValidateEmail($email) {
		// First, we check that there's one @ symbol,
		// and that the lengths are right.
		if (!ereg("^[^@]{1,64}@[^@]{1,255}$", $email)) {
			// Email invalid because wrong number of characters
			// in one section or wrong number of @ symbols.
			return false;
		}
		// Split it into sections to make life easier
		$email_array = explode("@", $email);
		$local_array = explode(".", $email_array[0]);
		for ($i = 0; $i < sizeof($local_array); $i++) {
			if
			(!ereg("^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$",
			$local_array[$i])) {
				return false;
			}
		}
		// Check if domain is IP. If not,
		// it should be valid domain name
		if (!ereg("^\[?[0-9\.]+\]?$", $email_array[1])) {
			$domain_array = explode(".", $email_array[1]);
			if (sizeof($domain_array) < 2) {
				return false; // Not enough parts to domain
			}
			for ($i = 0; $i < sizeof($domain_array); $i++) {
				if
				(!ereg("^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$",
				$domain_array[$i])) {
					return false;
				}
			}
		}
		return true;
	}
 
 
}
?>
 
 
 
 
<-- contact.us.js -->
 
var http;
 
//this function gets XMLHTTPRequest object independently from the browser 
function getXMLHTTPRequest() {
try {
	req = new XMLHttpRequest();
	} 
catch(err1) {
    try {
    	req = new ActiveXObject("Msxml2.XMLHTTP");
    	} 
    catch (err2) {
        try {
        	req = new ActiveXObject("Microsoft.XMLHTTP");
        	} 
        catch (err3) {
            req = false;
        	}
    	}
	}
return req;
} 
 
function urlencode(str) {
	return escape(str).replace('+', '%2B').replace('%20', '+').replace('*', '%2A').replace('/', '%2F').replace('@', '%40');
}
 
function CUHideForm()
{
	document.getElementById('CUdiv').style.display='none';
}
 
function CUSubmit(url)
{
	document.getElementById('CUstatus').innerHTML = '<img src="load.gif" /> Sending...';
	params = 'name='+urlencode(document.forms['CUform'].CUname.value);
	params += '&email='+urlencode(document.forms['CUform'].CUemail.value);
	params += '&subject='+urlencode(document.forms['CUform'].CUsubject.value);
	params += '&message='+urlencode(document.forms['CUform'].CUmessage.value);
	http = getXMLHTTPRequest();
	http.open("POST",url,true);
	http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	http.setRequestHeader("Content-length", params.length);
	http.setRequestHeader("Connection", "close");
	http.onreadystatechange = CUStateChange;
	http.send(params);	
}
 
function CUStateChange()
{
	try
			{
	
			if (http.readyState == 4){
				if (http.status == 200)
				{
					if (http.responseXML)
					{
						var s = http.responseXML.getElementsByTagName('status');
						var status = s[0].firstChild.data;
            			if (status == 'error')
            			{
            				var e = http.responseXML.getElementsByTagName('error');
            				var err = e[0].firstChild.data;
            				document.getElementById('CUstatus').innerHTML = err;
            			}
            			else if (status == 'ok')
            			{
        					document.getElementById('CUstatus').innerHTML = 'Your contact info was succesfully sent.';
        					CUHideForm();
            			}
					}
				}
				else
				{
					document.getElementById('CUstatus').innerHTML = 'There was a http error: '+http.status;
				}
				
			}
			}
			catch (err)
			{
				document.getElementById('CUstatus').innerHTML = 'Unknown error occured.';
				
			}
}

Open in new window

load.gif
0
 

Author Comment

by:thyros
ID: 22775474
Thanks for your posts.  I will try to test these out and let you know how I get on.

I'd also like to mention that we are using the JQuery library on our site, in case that makes any difference.
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
This article discusses how to create an extensible mechanism for linked drop downs.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

785 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question