Solved

Simple Secure Contact Us Form Page Script

Posted on 2008-10-21
4
660 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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

760 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now