Coding DetailsView the source code for this ASP script.
The script is fairly simple with four basic steps.
- Check the request to ensure a valid form submission.
- Process (most of) the control form fields passed.
- If no errors occured in the previous steps, create and send the email.
- Produce an output page displaying either errors or the data that was emailed.
Note that the script does not necessarily stop processing when an error occurs. Instead, error messages are stored in a global array and processing continues where possible. Then all the error messages can be displayed on the final step.
The details for each step are discussed below.
Checking for a Valid Form Submission
The script first checks for form data in the request, no data means that there is nothing to process.
'Check for form data. if Request.ServerVariables("Content_Length") = 0 then call AddErrorMsg("No form data submitted.") end if
Then it does the bot check (if enabled).
'If bot checking is enabled, check the elapsed time. if botCheckFlag then startTime = Session(botCheckID) if not IsDate(startTime) then call AddErrorMsg("Invalid submission.") elseif DateDiff("s", startTime, Now()) < botCheckMinTime then call AddErrorMsg("Invalid submission.") end if end if
The next check is to determine if the host in the referering URL is permitted.
'Check if the referering host is allowed. if UBound(allowedHosts) >= 0 then host = GetHost(Request.ServerVariables("HTTP_REFERER")) if host = "" then call AddErrorMsg("No referer.") elseif not InList(host, allowedHosts) then call AddErrorMsg("Unauthorized host: '" & host & "'.") end if end if
HTTP_REFERER environment variable contains the URL of the
form that submitted the request. This is passed to the
function which parses out the host name, i.e. the characters between the the
beginning "http://" (or "https://") and the next "/" character.
The script then looks in the
allowedHosts list for a match. Any
requests from an unauthorized host name generates an error message.
Processing the Control Fields
The only required control field is
_recipients. The script
ensures that at least one recipient is specified. It then checks that each
is a valid email address and is permitted via the
'Check the email recipients. if Request.Form("_recipients") = "" then call AddErrorMsg("No email recipient(s) specified.") else recipients = Split(Request.Form("_recipients"), ",") for each addr in recipients addr = Trim(addr) if not IsValidEmailAddress(addr) then call AddErrorMsg("Invalid email address in recipient list: " _ & addr & ".") elseif UBound(allowedRecipients) >= 0 then if not inList(addr, allowedRecipients) then call AddErrorMsg( _ "Unauthorized email address in recipient list: " & addr & ".") end if end if next recipients = Join(recipients, ",") end if
Next is the
field. These work a little differently. The value is taken to be the name of
another field present in the form data. The script takes the value of this
other field to be used as the
'Check for a cc-to or reply-to address. ccToAddr = "" replyToAddr = "" name = Trim(Request.Form("_ccToField")) if name <> "" then if not allowCcToFlag then call AddErrorMsg( _ "Configuration error: use of _ccToField not permitted.") else ccToAddr = Request.Form(name) if ccToAddr <> "" then if not IsValidEmailAddress(ccToAddr) then call AddErrorMsg("Invalid email address in " & name _ & " field: " & ccToAddr & ".") end if end if end if else name = Trim(Request.Form("_replyToField")) if name <> "" then replyToAddr = Request.Form(name) if replyToAddr <> "" then if not IsValidEmailAddress(replyToAddr) then call AddErrorMsg("Invalid email address in " & name _ & " field: " & replyToAddr & ".") end if end if end if end if
Note that if
_ccToField is used,
will be ignored.
Again, since the resulting value is suppose to be an email addresses, it is checked to ensure it is in the correct format.
The script then gets the email subject line from the
'Get the subject text. subject = Request.Form("_subject")
_requiredFields control field is processed next. Like
_recipients, it may have multiple values separated by commas, so
these checked individually. And like
_ccToField, those values are taken to be the names of other form
'If required fields are specified, check them. if Request.Form("_requiredFields") <> "" then required = Split(Request.Form("_requiredFields"), ",") for each name in required name = Trim(name) if Left(name, 1) <> "_" and Request.Form(name) = "" then call AddErrorMsg("Missing value for " & name) end if next end if
If any of the specified fields has a null string value, an error message is generated. Note that any field whose name starts with an underscore is ignored, as that is reserved for the control fields.
_fieldOrder control field is handled next, resulting in an
array of field names which will be used to display the form fields in that
'If a field order was given, use it. Otherwise use the order the fields 'were received in. str = "" if Request.Form("_fieldOrder") <> "" then fieldOrder = Split(Request.Form("_fieldOrder"), ",") for each name in fieldOrder if str <> "" then str = str & "," end if str = str & Trim(name) next fieldOrder = Split(str, ",") else fieldOrder = FormFieldList() end if
Generating the Email
If no errors have been detected so far, the next step is building the email. The script contructs the body of the email note, using HTML formatting.
'If there were no errors, build the email note and send it. if UBound(errorMsgs) < 0 then 'Build table of form fields and values. body = "<table border=""0"" cellpadding=""2"" cellspacing=""0"">" _ & vbCrLf for each name in fieldOrder body = body _ & "<tr valign=""top"">" _ & "<td><strong>" & name & ":</strong></td>" _ & "<td>" & Request.Form(name) & "</td>" _ & "</tr>" & vbCrLf next body = body & "</table>" & vbCrLf
Note the use of the
fieldOrder array. It is simply an array of
field names generated in the previous step using either the
_fieldOrder control field or (when that control field is not used)
by a function called
This function corrects a small problem with VBScript. While it's possible to simply loop through all the form fields using a statement like...
for each name in Request.Form ... next
VBScript doesn't guarantee that the field names will be given in the same order as they appear in the form request sent by the browser.
To ensure that the fields are listed in the order received, the
FormFieldList() function is used to generate the names in an
array in the proper order.
_envars control field is checked here to append a display
of any requested environmental variables to the email.
'Add a table for any requested environment variables. if Request.Form("_envars") <> "" then body = body _ & "<p> </p>" & vbCrLf _ & "<table border=""0"" cellpadding=""2"" cellspacing=""0"">" _ & vbCrLf envars = Split(Request.Form("_envars"), ",") for each name in envars name = Trim(name) 'Only show environment variables in the permitted list. showEnvar = true if UBound(allowedEnvars) >= 0 then showEnvar = InList(name, allowedEnvars) end if if showEnvar then body = body _ & "<tr valign=""top"">" _ & "<td><strong>" & name & ":</strong></td>" _ & "<td>" & Request.ServerVariables(name) & "</td>" _ & "</tr>" & vbCrLf end if next body = body & "</table>" & vbCrLf end if
Now the email can be sent. If an error occurs when attempting to send it, the error message is saved for display.
'Send it. str = SendMail() if str <> "" then AddErrorMsg(str) else 'Clear the bot check timestamp. Session.Contents.Remove(botCheckID) 'Redirect if a URL was given. if Request.Form("_redirectUrl") <> "" then Response.Redirect(Request.Form("_redirectUrl")) end if end if
Displaying the Results
The final step is to build a page for display. If any errors were
encountered, these are listed. Otherwise, the script checks for the
_redirectUrl control field
If a redirect URL was specified, it redirects to that page. If not, the
script builds a simple display of the fields included in the email. If a URL
was specified in the
_continueUrl control field, it adds a link
to it at the bottom of the page.