?
Solved

Simple Secure Contact Us Form Page Script

Posted on 2008-10-21
4
Medium Priority
?
675 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
4 Comments
 
LVL 8

Accepted Solution

by:
MatthiasVance earned 1000 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 1000 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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This article discusses four methods for overlaying images in a container on a web page
There are times when I have encountered the need to decompress a response from a PHP request. This is how it's done, but you must have control of the request and you can set the Accept-Encoding header.
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…
Suggested Courses

764 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