|
Chapter 1, Active Server Pages: An Introduction, provided a brief introduction
to
Active Server Pages and how they can be used to dynamically create HTML
content. In this chapter, you will learn more about whats going
on behind the
scenes. First well review scripting, scripting hosts, and scripting
languages. You
will learn about how Active Server Pages (the actual ASP.DLL) works to
interpret
your server-side code to create HTML and how IIS then inserts that dynamically
created HTML into the HTML stream.
Client-Side Scripting
The Hypertext Markup Language, or HTML, provides for very detailed formatting
of static textual content. This content can contain images, tables, and
carefully
formatted text and hyperlinks, making for a very powerful medium through
which
to present information. However, aside from the very low level interactivity
of
hyperlinks and their ability to move the user from one page to another
in a stream
of information flowing from one page to another, HTML by itself allows
for no
true interactivity. HTML does not allow the web page to react to user
input in any
way beyond navigating to another page. HTML is an excellent way to allow
for the
presentation of information but does not allow for the interactivity required
to
transform web pages from an information medium to a dynamic web application
solution.
Netscape Communications along with Sun Microsystems created a solution
called
LiveScript that allowed for the inclusion of limited programming instructions
that
reside in web pages viewed using the Netscape Navigator browser on the
client
machine. This programming language was limited in its ability to interact
with the
users machine outside the browser and slowly over an evolving process
was
made safe and secure. You could not use LiveScript programming instructions
on
the client machine to undermine the security innate to the Netscape Navigator
browser. LiveScript, in accordance with the marketing frenzy surrounding
Java,
was quickly renamed to JavaScript. Unfortunately, this renaming has led,
errone-
ously, to its being thought of by many as a subset of the powerful Java
language,
although only its syntax is similar to that of Java.
HTML was enlivened. Using JavaScript, you could build forms and mortgage
calculators
and all sorts of interactive web pages. The only drawback was that your
browser had to be a scripting host for this scripting language. But that
being said,
web content quickly went from being static and largely simple to being
interactive
and alive.
Before JavaScript, all interaction with the user and all reaction on the
part of the
web server required the use of sophisticated web server applications and
higherend
web server machines. With the advent of JavaScript, the users machine
was
now added to the equation, making it possible to offload some of this
computational
power onto the client, whereas before it had rested solely on the server.
Not to be outdone, Microsoft Corporation quickly created a scripting language
of
its own: Visual Basic, Scripting Edition, or VBScript for short. VBScript
is a subset
of the Visual Basic for Applications language and, like JavaScript, it
allows for the
creation of interactive web pages. Unlike JavaScript, whose syntax was
similar to
that of Java (and thus similar to that of C++), the syntax of VBScript
was exactly
that of Visual Basic. If you knew Visual Basic (and many, many people
do), you
already had a good grasp on VBScript. Furthermore, Microsoft also created
its own
version of JavaScript called JScript that was similar but not identical
to its
predecessor.
Today (only a few short years later), JavaScript has undergone a transformation
into a new language built using submissions from both Netscape and Microsoft.
This new language is called ECMAScript (from European Computer Manufacturers
Association). According to David Flanagan in JavaScript: The Definitive
Guide, this
name was chosen specifically because it had no relation to either parent
company
and it had none of the marketing glitz of Java artificially associated
with it. Both
Netscape and Microsoft have continued to help ECMAScript (still called
JavaScript
by everyone except members of the European Computer Manufacturers Association)
evolve. For more details on the different browsers implementations,
Flanagan provides excellent coverage in his book.
Although the preceding discussion suggests that only JavaScript and VBScript
exist,
the web browser actually allows for a multitude of scripting language
alternatives.
You could even build your own. Some of the other languages include PerlScript,
Python, and Awk, with PerlScript being the most popular after JavaScript
and
VBScript.
One thing all scripting languages have in common, however, is how they
are
included on a web page and how the browser recognizes them as script and
not
as HTML. All script is surrounded by matching <SCRIPT></SCRIPT>
tags, as the
three examples of client-side script in Example 2-1 illustrate. Each of
the three
routines performs exactly the same action: each displays a message box
(or alert
box, depending on your preference of nomenclature) on the screen containing
the
words Hello world.
There are two features in Example 2-1 to notice. The first is how the
actual code is
surrounded by HTML comment symbols:
<!--
code here
-->
This lets the page be shown in browsers that do not support the <SCRIPT>
tag
without causing problems or displaying the script on the page.
The second feature is the LANGUAGE attribute in each piece of sample code.
The
LANGUAGE attribute of the <SCRIPT> tag, as youve undoubtedly
guessed, indicates
what scripting language the browser should use to execute the included
code. This can be any language that your browser supports. JavaScript
is probably
the safest bet for client-side scripting, since VBScript is supported
only with the
use of plugins in non-Microsoft browsers, and other scripting languages
are not
commonly installed on user machines. For more information about JavaScript,
see
David Flanagans excellent book, JavaScript: The Definitive Guide,
3rd Edition. For
more information about VBScript, see Learning VBScript, by Paul Lomax.
Both are
published by OReilly & Associates. Well revisit the question
of scripting
languages at the end of this chapter.
Example 2-1: Client-Side Scripting Using Three Scripting Languages
<SCRIPT LANGUAGE = "JavaScript">
<!-
Function AlertJS()
{
alert("Hello world.")
}
-->
</SCRIPT>
<SCRIPT LANGUAGE = "VBScript">
<!-
Sub AlertVBS()
MsgBox "Hello world."
End Sub
-->
</SCRIPT>
<SCRIPT language="PerlScript">
<!-
sub AlertPS()
{
$window->alert("Hello world.");
}
-->
</SCRIPT>
Server-Side Scripting
The last section served to introduce you to client-side scripting: how
to include
scripting code in the web pages that are viewed by your users. Now you
will learn
how to bring the power of scripting to the server and harness it to dynamically
create HTML in reaction to user requests.
As you will recall from the last chapter, when the browser makes a request
for a
file ending with the .ASP file extension, IIS knows to bring ASP.DLL into
play to
interpret the ASP code in the file. Once interpreted, the results of this
code are
placed into the document, which is a simple HTML document before it is
sent to
the user.
How does ASP.DLL know which code to interpret? The answer to this question
is
the key to executing code on the server. ASP.DLL interprets all code in
a file (with
the .ASP file extension) thats delimited with <%
%> as
being ASP code. (There is
another way to delineate server-side code that Ill cover in a moment.)
Example 2-2 shows an active server page named ExampleChap2.asp, with the
VBScript code that will be interpreted by ASP.DLL in bold.
When a user requests ExampleChap2.ASP, IIS pulls the file from the file
system
into its memory. Recognizing the .ASP extension from the settings in the
Management
Console, it uses ASP.DLL to read and interpret the file. Once interpreted,
IIS
sends the final result down to the requesting client browser.
IIS handles all the HTTP traffic. ASP.DLL only interprets server-side
code, pulling
in the DLL of the appropriate scripting engine when necessary. Lets
assume the
time is 10:42:43. The previous ASP file, once interpreted, would result
in the
following dynamically created HTML page that will in turn be sent to the
client by
IIS:
<HTML>
<HEAD><TITLE>Example</TITLE></HEAD>
<BODY>
Hello. It is now 10:42:43 on the server.
</BODY>
</HTML>
Example 2-2: ExampleChap2.asp
<HTML>
<HEAD><TITLE>Example</TITLE></HEAD>
<BODY>
<%
' Construct a greeting string with a salutation and the
' current time on the server (retrieved from the Time()
' function) and then display that in the HTML sent to the
' client.
strGreetingMsg = "Hello. It is now " & Time() & _
" on the server."
Response.Write strGreetingMsg
%>
</BODY>
</HTML>
You will learn more about the Write method of the Response object in Chapter
7,
Response Object. For now, recognize it as one way of writing information
from the
portion of the script that is interpreted on the server to the portion
of HTML that
will be displayed on the browser.
It is important to recognize this for what it is. There is no magic here.
We are
simply capturing the HTTP request. Then ASP.DLL interprets some code and
alters
the HTTP response that is sent back to the client.
ASP.DLL is an ISAPI filter that alters the resulting HTTP response
stream in reaction to information in the HTTP request combined
with code in the requested document.
The Response.Write method call is one way of inserting code into the HTML
stream that is sent back to the client, but there is a shortcut for this
method call:
the <%=
%> delimiters. Note the inclusion of the equal sign
(=). The equal sign is
what differentiates this as a shortcut call to the Response.Write method
and not
simply more ASP code to interpret.
The <%=
%> delimiters allow for some subtle effects that can
allow you to
produce some powerful server-side/client-side HTML combinations. Here
is
Example 2-2 rewritten using the <%=
%> delimiters:
<HTML>
<HEAD><TITLE>Example</TITLE></HEAD>
<BODY>
Hello. It is now <%=Time()%> on the server.
</BODY>
</HTML>
Using the <%=
%> delimiters is the same as using the Write
method of the
Response object. It simply inserts into the HTML stream whatever is between
the
opening <%= and the closing %>. If the content between the delimiters
represents a
variable, that variables value is inserted into the HTML stream.
If the content is a
call to a function, the result of the function call is inserted into the
HTML stream.
With the careful use of these delimiters, you can dynamically construct
not only
HTML content but also client-side script code, as Example 2-3 demonstrates.
The
script is called DynamicForm.asp, and it accepts a single parameter, button_
Count. Based on the value of button_Count, DynamicForm.asp will dynamically
build between one and ten HTML submit buttons and also dynamically generate
script for the onClick events for each of them. We will discuss this script
in detail.
Example 2-3: DynamicForm.asp
<HTML>
<HEAD><TITLE>DynamicForm.asp</TITLE></HEAD>
<BODY>
Welcome to the dynamic form!
<%
' Retrieve the number of buttons the user wishes to create.
Suppose we call this script with the following line:
/DynamicForm.asp?button_Count=3
The result appears in Figure 2-1, and the resulting HTML source is shown
in
Example 2-4.
intCmdCount = Request.QueryString("button_Count")
' Ensure that the sent parameter is within the acceptable
' limits.
If intCmdCount < 1 Then
intCmdCount = 1
End If
If intCmdCount > 10 Then
intCmdCount = 10
End If
' Create the buttons.
For intCounter = 1 to intCmdCount
%>
<INPUT TYPE = button VALUE = Button<%=intCounter%>
OnClick = "Button<%=intCounter%>_Click()">
<%
Next
%>
<SCRIPT LANGUAGE = "VBScript">
<%
' Create the scripts for each of the created buttons.
For intCounter = 1 to intCmdCount
%>
Sub Button<%=intCounter%>_Click()
MsgBox "You just clicked button <%=intCounter%>."
End Sub
<%
Next
%>
</SCRIPT>
</BODY>
</HTML>
The parameter button_Count=3 translated into the construction of three
HTML
button elements and the corresponding code to go with them. Note the names
and
the onClick event procedure names for each of these buttons (in bold in
the
following code):
<INPUT TYPE = button VALUE = Button1
OnClick = "Button1_Click()">
Figure 2-1: The web page that results from invoking DynamicForm.ASP
Example 2-4: HTML Source Produced by DynamicForm.ASP
<HTML>
<HEAD><TITLE>DynamicForm.asp</TITLE></HEAD>
<BODY>
Welcome to the dynamic form!
<INPUT TYPE = button VALUE = Button1
OnClick = "Button1_Click()">
<INPUT TYPE = button VALUE = Button2
OnClick = "Button2_Click()">
<INPUT TYPE = button VALUE = Button3
OnClick = "Button3_Click()">
<SCRIPT LANGUAGE = "VBScript">
Sub Button1_Click()
MsgBox "You just clicked button 1."
End Sub
Sub Button2_Click()
MsgBox "You just clicked button 2."
End Sub
Sub Button3_Click()
MsgBox "You just clicked button 3."
End Sub
</SCRIPT>
</BODY>
</HTML>
<INPUT TYPE = button VALUE = Button2
OnClick = "Button2_Click()">
<INPUT TYPE = button VALUE = Button3
OnClick = "Button3_Click()">
These button element names and event procedure titles each came from the
following line of code:
<INPUT TYPE = button VALUE = Button<%=intCounter%>
OnClick = "Button<%=intCounter%>_Click()">
Note that the result of <%=intCounter%> is inserted into the HTML
text stream.
Using ASP, we were able to dynamically generate names for each of our
buttons
by appending the value of a counter variable onto the end of the word
Button in
the HTML stream.
This is a subtle point. One of the most common errors in ASP development
is to
treat the result of <%=
%> as a variable name. For example,
the following line of
server-side code does not result in the greeting Hello Margaret,
though some
developers mistakenly believe it does:
<%
' INCORRECT CODE.
strUserName = "Margaret"
%>
MsgBox "Hello " & <%=strUserName%>
When the preceding is sent to the client, it will appear like this:
MsgBox "Hello " & Margaret
VBScript tries diligently to make something of the token Margaret, but
the result
is shown in Figure 2-2.
The correct line of code to produce the desired result is the following:
MsgBox "Hello <%=strUserName%>"
The point here is that whats in the <%=
%> delimiters
comes into the HTML
stream as is, even inside a string. Whatever the value of the content
is, that is what
is inserted into the HTML stream. Do not treat <%=
%> as a
variable.
ASP Functions
Code reuse is as important in Active Server Pages as it is in any other
form of
application programming. The first example of code reuse is the ASP function
or
subroutine. As I mentioned in the beginning of this chapter, there is
one other
Figure 2-2: Treating the result of <%=...%> as a variable name
way to delineate server-side code: the RUNAT attribute of the <SCRIPT>
tag. You
can use the RUNAT attribute to specify that a particular function or subroutine
is to
be run (and called from) the server side. Example 2-5 demonstrates the
use of the
RUNAT attribute to create a simple function that uses the last three letters
of the
domain string to return the general type of site that it represents. This
function
takes a domain string such as www.oreilly.com and returns the string company.
The RUNAT attribute instructs ASP that this is a server-side-only function.
It will not
be sent to the client and is a valid function to call from within the
server-side
code. We could now incorporate that into a script, as shown in Example
2-6.
Example 2-5: Using the RUNAT Attribute to Create a Server-Side Function
<SCRIPT LANGUAGE = "VBScript" RUNAT = SERVER>
Function DomainType(strDomainString)
strPossibleDomain = Right(strDomainString, 3)
Select Case Ucase(strPossibleDomain)
Case "COM"
DomainType = "company"
Case "EDU"
DomainType = "educational"
Case "GOV"
DomainType = "government_civil"
Case "MIL"
DomainType = "government_military"
Case Else
DomainType = "UNKNOWN"
End Select
End Function
</SCRIPT>
Example 2-6: Including a Server-Side Function in an ASP
<HTML><HEAD><TITLE>Function Example</TITLE></HEAD>
<BODY>
<%
' In this script we'll simply initialize a string
' example parameter, but this value could have
' come from another script.
strDomainString = "perl.ora.com"
strDomainType = DomainType(strDomainString)
%>
<%=strDomainString%> is a <%=strDomainType%> site.
</BODY>
</HTML>
<SCRIPT LANGUAGE = "VBScript" RUNAT = SERVER>
Function DomainType(strDomainString)
strPossibleDomain = Right(strDomainString, 3)
The script in Example 2-6, once interpreted, generates and sends the following
script to the client:
<HTML>
<HEAD><TITLE>Function Example</TITLE></HEAD>
<BODY>
perl.ora.com is a company site.
</BODY>
</HTML>
Note that neither the text between the <%
%> delimiters nor
the DomainType
function is present in the resulting HTML.
The script in Example 2-6 also demonstrates that we need not place our
serverside
functions within the <HTML>
</HTML> tags. However, if
we do (as in
Example 2-7), the resulting HTML will be exactly the same as it was before.
The
server-side function is still not inserted into the HTML stream, even
when we place
it inside the <BODY> tags.
Select Case Ucase(strPossibleDomain)
Case "COM"
DomainType = "company"
Case "EDU"
DomainType = "educational"
Case "GOV"
DomainType = "government_civil"
Case "MIL"
DomainType = "government_military"
Case Else
DomainType = "UNKNOWN"
End Select
End Function
</SCRIPT>
Example 2-7: Script Placed Within the <HTML>
</HTML>
Tags
<HTML>
<HEAD><TITLE>Function Example</TITLE></HEAD>
<BODY>
<%
' In this script we'll simply initialize a string
' example parameter, but this value could have
' come from another script.
strDomainString = "perl.ora.com"
strDomainType = DomainType(strDomainString)
%>
<%=strDomainString%> is a <%=strDomainType%> site.
<SCRIPT LANGUAGE = "VBScript" RUNAT = SERVER>
Function DomainType(strDomainString)
strPossibleDomain = Right(strDomainString, 3)
Scripting Languages
You do not have to use one single language for the entire ASP application.
There
is no problem with mixing and matching for convenience. I typically use
VBScript
in server-side code and JavaScript on the client, but you are not forced
to use a
single language in either setting. You can, however, force ASP to default
to a
specific script by using the @LANGUAGE preprocessor ASP directive. ASP
directives
are covered in Chapter 10, Preprocessing Directives, Server-Side Includes,
and
GLOBAL.ASA. For now, know that you can use the following line of code
as the
first in your script to force ASP to use JScript as the default scripting
language
when interpreting your code:
<%@ LANGUAGE = JScript%>
If you place this line anywhere but as the first line, you will receive
an error. Also
note that VBScript is the default for all server-side scripts. However,
you can
change this in the Application options for your ASP applications
virtual directory.
See Appendix C, Configuration of ASP Applications on IIS.
Select Case Ucase(strPossibleDomain)
Case "COM"
DomainType = "company"
Case "EDU"
DomainType = "educational"
Case "GOV"
DomainType = "government_civil"
Case "MIL"
DomainType = "government_military"
Case Else
DomainType = "UNKNOWN"
End Select
End Function
</SCRIPT>
</BODY>
</HTML>
|