Chapter 23 -- Client-Side Scripting
Chapter 23
Client-Side Scripting
CONTENTS
Client-Side Scripting and Security
An Introduction to JavaScript
An Introduction to VBScript
Client-Side Scripting Check
One clear way to extend the power of the HTTP protocol is by increasing
the processing power of the client. If the client's Web browser
was able to interpret logical instructions (program code) as well
as render HTML, for example, such tasks as form input validation
might be accomplished on the client side without a roundtrip to
the server. This is quite a bit different than the CGI paradigm,
where any client data submission must travel to the server, which
then spawns a CGI process to handle the client data. If the client
can interpret program instructions and execute logic local to
the client machine, the server load can be lessened and the overall
flow of data from client to server made more efficient. Both Netscape
Communications Corporation, with its JavaScript product, and Microsoft,
with its VBScript product, offer this type of HTML extension.
The program code is embedded in the HTML masquerading as a comment-hopefully
so that noncompliant browsers will ignore the code altogether.
The concept is that compliant browsers will run the logical code
with built-in interpreters. Listing 23.1 shows what JavaScripts
look like.
Listing 23.1. A general JavaScript template.
<HTML>
<HEAD>
<TITLE> My Script Page </TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE = JavaScript>
<!-- put this comment here to try to protect from
noncompliant browsers
... script code here ...
// -->
</script>
</body>
</html>
We also see scripts that are embedded in the <HEAD>
section; in fact, scripts can be embedded in both the <HEAD>
and the <BODY> sections.
The same is true for VBScript; just replace the word JavaScript
in Listing 23.1 with VBScript
(or VBS, in earlier incarnations
of the product).
Warning
By including proprietary script code in an HTML page, the developer is making a de facto assumption that the benefits of the clientside logic outweigh the risks of the code behaving erratically on a semicompliant rival browser, breaking on a
noncompliant browser, or breaking on a more advanced version of the optimal browser.
Note the fundamental paradox: The Web bills itself as an interoperable
environment, where clients in an architecture-neutral manner can
interact with servers. Yet, vendors must compete for market share
by developing proprietary (non-interoperable) tools.(See note)
Thus, I see many pages on the Web that state something like "Netscape
Now!" or "Best Experienced with Free Microsoft Internet
Explorer"-rather obvious brand differentiation, which is
standard fare in a Marketing MBA class. The truth, necessarily,
is that vendors are gambling with first-mover developments; a
script language that runs on one vendor's browser is either going
to not run at all or run erratically on another vendor's browser.
We thus move away from the openness envisioned by the HTTP protocol
developers and start to get into the sticky ground of market share
competition. Worse, within the same vendor, upgrades to a browser
may well not be backward-compatible to prior versions of the script
interpreter. Thus, scripts that run in Netscape 3.x products
might well require the 3.x browser and not run on Netscape
2.x, for example. Developers then are placed in the awkward
position of coding explicit logic to check for the version number-not
an optimal state of affairs. Having said this, it is still important
to cover JavaScript and VBScript because, although they choose
to go their own way, they still are quite prevalent on the Net,
and their object-oriented flavor is instructive to examine.
This chapter is not meant to be an exhaustive treatise on the
syntax of JavaScript or VBScript. Instead, I present a broad comparison
of the two products, examine two sample applications in each language,
and return at the end to a broad discussion of the advantages
and disadvantages of incorporating client-side scripts into an
HTML page.
Client-Side
Scripting and Security
Inserting logic into an HTML page is quite a powerful and quite
a dangerous idea. Consider the malicious author (let's call this
person the attacker), who is seeking a way to interfere
with the client (user) computer's proper operation. This
broad danger might manifest itself specifically as issuing surreptitious
commands from the user's computer, deleting or changing files
on the user's local disk drive(s), or tracking the user's keystrokes
(an invasion of privacy). Now consider the architects of a generic
scripting engine; let's call them the builders. They must
build an engine to interpret their scripting language and couch
this interpreter inside a specific browser (a JavaScript interpreter
inside Netscape, for example, or a VBScript Interpreter inside
Microsoft's Internet Explorer). We can model this as a war; the
builders come out with an interpreter-let's call it Version 1.0-and
claim they have removed all unsafe operations from the interpreter.
In other words, the attacker is foiled at every turn by the interpreter
at runtime. Wait! A good citizen, posing as an attacker, demonstrates
how the interpreter can be duped or circumvented into allowing
an attack. The builders fix the publicly circulated problem in
a bug-fix release-let's say Version 1.1. The problem with the
security model here is that there is no model! Instead, there
is an endless cycle of attack and defense against a runtime interpreter.
The user places infinite trust in the builders to circumvent attacks
now and into the future; such trust is not and cannot be watertight.
It is important to contrast this with the quite different security
model of Sun Microsystems' distributed programming language-Java.
In Java, source code is compiled by a special compiler into bytecode
and the compiler checks for unsafe operations (this is known as
algorithmic security). Many unsafe operations stem from
the programmer trying to access unknown memory segments with pointers.
The Java compiler disallows these attempts. Only bytecode passed
by the compiler can be sent across TCP/IP from the server to the
client. The bytecode, which runs in a Java virtual machine, is
essentially architecture neutral and the client can run the program
on various platforms. The theoretical basis of Java security has
not been defeated; some clever researchers have discovered flaws
in the implementation of the model, but the underpinnings (a safe
compiler) remain intact. On the other hand, runtime interpreter
engines invite attack both on the browser version number and the
operating system platform on which they are running. The power
of the Java programming model is well advertised by the fact that
Microsoft has announced plans to add Java support to its NT operating
system kernel.
An
Introduction to JavaScript
JavaScript, an invention of Netscape Communication Corporation,
takes its name from the immensely popular Sun Microsystems' language
Java, yet the two have very little in common. Java, as mentioned
earlier, is bytecode compiled by a safe compiler and then distributed
from the server to the client. JavaScript is logic embedded into
an HTML page that runs immediately on the client machine. JavaScript's
first incarnation was LiveScript, but Netscape decided to cash
in on Java's popularity and renamed the product. The fact that
JavaScript contains the term Java has caused boundless
confusion on the Net. I recommend that the reader logically decouple
the two products.
JavaScript is object-based. An HTML form has methods, buttons
have methods, and images have methods, for example. It's simplest
to think in terms of actions you can do to an object in addition
to attributes of the object; both actions and attributes can be
exploited by script logic. However, keep in mind that Java is
a fully object-oriented language. Everything in Java must be expressed
in terms of a class. Not so in JavaScript; scripts might simply
be a series of expressions or alert dialog boxes and not reference
any objects. Detractors have criticized JavaScript since its inception
as LiveScript as a quick hack, but Netscape continues to enhance
the feature set, and it will be interesting to see how it can
integrate elements of the language into Web standards' initiatives.
Security and JavaScript
My earlier discussion of the weakness of JavaScript's approach
to security can be mapped directly into well-publicized attacks
on the JavaScript engine. John Robert LoVerso at the OSF Research
Institute,(See note) for example,
has had a lot of fun writing malicious JavaScripts to exploit
holes in various Netscape browser versions.
John has written scripts to stay resident even after the user
has left the scripted HTML page, for example, which is a problem
through Version 2.01. He also has been able to transmit to himself
the user's URL history (where he or she has been) without the
user's knowledge (an attack that persists until the user exits
the browser altogether). John also has demonstrated that he indeed
can write to the client's local file system (contrary to product
claims), although this does pop up a dialog box and is not transparent.
He also has been able to explore drives (including remote mounts)
and directories on client machines. All bugs have been reported
to Netscape, and John in fact was awarded a $1,000 Netscape bug
bounty prize. The history file (the user's URL cache) was acquired
via such an exploration.
JavaScript and Interoperability
Netscape is quite busy enhancing JavaScript from one browser release
to the next. Netscape 3, for example, saw a substantial increase
in the number of methods that can be applied to various HTML objects.
The changes are in no way backward compatible; Netscape 2.x
browsers will show strange and ugly foreground error messages
with many JavaScript 3.x function calls. Although I will
be showing code logic that detects browser versions, the problem
also extends to operating system platforms and other vendors'
browsers. How can a competitor (such as Microsoft) fully support
JavaScript the instant a new Netscape browser comes out, for example?
Such support is unrealistic to expect. Of course, Netscape cannot
support Microsoft VBScript for the same reasons. The vendors,
in their fight for market share, want to steer the user community
into using a browser that understands their scripts and their
"cool features"; by ignoring the standards process,
the entire Internet community suffers to some degree. Furthermore,
in a corporate multiplatform (or even multiversion!) environment,
proprietary script solutions cannot be justified; they are not
production quality. The flip side is that some developers simply
don't care about Netscape's competitors. They are willing to assume
that their user community uses a compliant browser. Even if this
assumption is unpalatable, the following samples should be of
interest: the quirky JavaScript syntax still is interesting and
does afford visually appealing functionality on Netscape browsers.
Netscape is pushing forward with JavaScript innovations. Netscape
3.0 beta 5, for example, uses the NOSCRIPT
... </NOSCRIPT> tag pair to wrap HTML that will
run if JavaScript is turned off in the Netscape preferences, or
if the client has an incompatible browser. Another feature to
improve HTML readability and script modularity is the optional
SRC attribute at the script's
start. For example,
<SCRIPT LANGUAGE=JavaScript SRC=test.js>
runs the JavaScript contained in the file test.js.
For more information, consult Netscape's Web pages (although,
recently, it has some JavaScript off-line). Jerry Currie has created
an MS-Windows Help resource for JavaScript at http://www.jchelp.com.
JavaScript Application Samples and Code Discussion
As promised, I'm not going to present an exhaustive (an exhausting!)
syntax guide to JavaScript. Instead, I will show a few interesting
small applications and discuss selected code techniques so that
you can get a feel for the language.
Image-Handling with JavaScript
The first JavaScript application you'll look at shows HTML form
interaction with JavaScript and the capability of JavaScript to
instantiate a new window with customized properties.(See note)
Figure 23.1 shows the introductory screen of the application.
Note how users have two choices. They can use the upper pull-down
selection box to choose a GIF image to appear in a new window,
or they can use the lower pull-down selection to view an inline
GIF image.
Figure 23.1 : The user can elect to show a GIF image in a new window or render it inline.
You can look at an image in a new window. Figure 23.2 shows what
happens if Palm Trees is selected from the pull-down selection
box.
Figure 23.2 : JavaScript instantiates a new window to contain the GIF--a window without status bars or other frills. Multiple image windows can be opened.
It's also possible to display the images inline running a Netscape
3.x or better browser; this is the second pull-down selection
box on-screen, as illustrated in Figure 23.3.
Figure 23.3 : The script has a separate function to display images inline.
Now it's time to examine the code and understand how the script
accommodates the image handling shown in Figures 23.2 and 23.3.
Listing 23.2 shows the JavaScript and the attached HTML code.
Listing: 23.2. A JavaScript image previewer demo.
<HTML>
<HEAD>
<SCRIPT>
// JavaScript Image Preview Demo
// by Paul Colton
function display_image(form) {
selectionname
= form.imagename.options[form.imagename.selectedIndex].text;
selection = form.imagename.options[form.imagename.selectedIndex].value;
myWindow = window.open("",
"Preview", "toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,resizable=0,
copyhistory=0,width=200,height=255");
myWindow.document.open();
myWindow.document.write("<HTML><HEAD>");
myWindow.document.write("<TITLE>Preview</TITLE>");
myWindow.document.write("</HEAD><BODY
BGCOLOR=FFFFFF TEXT=000000>");
myWindow.document.write("<FORM><CENTER><B><FONT
SIZE=+1>" +
selectionname
+ "</FONT></B><HR>");
myWindow.document.write("<IMG
HSPACE=0 VSPACE=0 HEIGHT=150 WIDTH=150 " +
// SET THE FOLLOWING ADDRESS TO YOUR MACHINE
"SRC='http://jrc.livesoftware.com/ip/"
+ selection + "'>");
myWindow.document.write("<HR><FORM><INPUT
TYPE='button' VALUE='Close' " +
"onClick='window.close()'></FORM>");
myWindow.document.write("</CENTER>");
myWindow.document.write("</BODY></HTML>");
myWindow.document.close();
}
function changeImage(form)
{
selection = form.imagename.options[form.imagename.selectedIndex].value;
document.images[2].src = "http://jrc.livesoftware.com/ip/"
+ selection;
}
</SCRIPT>
<TITLE>JavaScript Image Previewer Demo</TITLE>
</HEAD>
<BODY BGCOLOR=FFFFFF TEXT=000000>
<CENTER>
<IMG WIDTH=346 HEIGHT=34 SRC="previewertitle.gif"><BR>
<IMG WIDTH=108 HEIGHT=26 SRC="../images/previewercredit.gif">
</CENTER>
Please select an image from the following image list.
To preview additional images, just move the preview window
to the side and select another image from the list. You do
not need to close the preview window.<p>
<FORM>
<CENTER>
<select NAME="imagename" onChange="display_image(this.form)">
<option value="image0.gif">Select An Image
<option value="image1.gif">Palm Trees
<option value="image2.gif">Sunset
</select>
</CENTER>
</FORM>
<HR WIDTH=75%>
<CENTER>
<H3>Netscape 3.0 Demo Using On-Screen Image Updating</H3>
<FORM>
<CENTER>
<TABLE>
<TR>
<TD valign=center align=center>
<IMG SRC="image0.gif">
</TD>
<TD valign=center align=center>
<SELECT SIZE=1 NAME="imagename" onChange="changeImage(this.form)">
<option value="image0.gif">Select An Image
<option value="image1.gif">Palm Trees
<option value="image2.gif">Sunset
</SELECT>
</TD>
</TR>
</TABLE>
</CENTER>
</FORM>
<HR>
<CENTER>
<FONT SIZE=-2>
Comments to <A HREF="mailto:contact@livesoftware.com">Live
Software</A>
</FONT>
</CENTER>
</BODY>
</HTML>
Consider the results of Figure 23.2 first. The user picked Palm
Trees from the form. If you look at Listing 23.2, you see that
the typical HTML form has been augmented:
<select NAME="imagename"
onChange="display_image(this.form)">
<option value="image0.gif">Select An Image
<option value="image1.gif">Palm Trees
<option value="image2.gif">Sunset
</select>
In other words, the script detects a change in this form setting
(the onChange method); this
corresponds to the user selecting an image. The function display_image
then is called with the current ("this")
form as an argument. That function is embedded in the <HEAD>
section near the top of the HTML; it uses the image selected by
the user and it instantiates (in object-oriented terminology)
a new window with the myWindow
assignment. The window.open
method defines the characteristics of myWindow
when it is opened. As you can see, it is going to be a plain vanilla
window without menubars, scrollbars, and so on; this is ideal
for an image viewer. The next line, myWindow.document.open(),
is the actual machine operation to start the new window, and then
a series of write statements
fill the window with HTML content.
The syntax construction certainly will look odd to readers who
are not used to object-oriented languages. With the immense popularity
of Perl 5 and Java, however, it is clearly time to start getting
used to the modular world of classes, objects, and methods.
Now turn to Figure 23.3. The user has picked an image from the
second pull-down list, and you see from the HTML code
<SELECT SIZE=1 NAME="imagename"
onChange="changeImage(this.form)">
<option value="image0.gif">Select An Image
<option value="image1.gif">Palm Trees
<option value="image2.gif">Sunset
</SELECT>
that, once again, the onChange
method is used to call the function changeImage
if the form variable imagename
changes. Examine the code of the function changeImage:
selection = form.imagename.options[form.imagename.selectedIndex].value;
document.images[2].src = "http://jrc.livesoftware.com/ip/"
+ selection;
This looks ominous, but it's really quite simple: the first line
assigns a variable, selection,
to the value of the image selected by the user. This might be
image0.gif, image1.gif,
or image2.gif. The second
line assigns the second GIF image on this HTML page (the Live
Software logo you see in Fig. 23.1) with the image selected by
the user, prepended by the virtual path to that GIF. If I wanted
to take this code and run it on my server, I would only have to
(probably) change the GIF offset from 2 to a value appropriate
for me, change the URL prefix to my GIFs, and change the names
of the GIFs in the HTML form.
Browser Detection and the OnMouse_Over
Method
The next JavaScript application we'll look at shows browser detection
techniques and also illustrates the mouse_over
method. When the user passes the mouse over an image, an action
can be taken (in this case, substituting another image for a certain
time interval and then reverting to the original image).(See note)
See Figure 23.4 for the screen appearance before I pass my mouse
over the Test GIF.
Figure 23.4 : The Test image is highlighted for two seconds when the user passes the mouse over it.
If I pass my mouse over the Test
image, it lights up for two seconds and then reverts to its inactive
(grayed out) state. How is this done? Let's look at the code shown
in Listing 23.3.
Listing 23.3. Preloading Images and the onMouseOver
method.
<HTML>
<HEAD>
<TITLE>JavaScript Tip of the Week for June 24, 1996: Too
Many Browsers? Wrong.</TITLE>
<SCRIPT LANGUAGE = "JavaScript">
var version = 0;
if(navigator.appName.indexOf("Netscape")
!= -1){
if(
navigator.userAgent.indexOf("Mozilla/3.0b3")
!= -1 ||
navigator.userAgent.indexOf("Mozilla/3.0b4")
!= -1 ||
navigator.userAgent.indexOf("Mozilla/3.0b5")
!= -1 ||
navigator.userAgent.indexOf("Mozilla/3.0b6")
!= -1 ||
navigator.userAgent.indexOf("Mozilla/3.0")
!= -1) {
version
= 3;
active
= new Image(105, 42);
active.src
= "test_active.jpg";
inactive
= new Image(105, 42);
inactive.src
= "test_inactive.jpg";
if
(navigator.userAgent.indexOf("Macintosh") != -1) {
version
= 4;
}
}
else
if(
navigator.userAgent.indexOf("Mozilla/2.0")
!= -1 ||
navigator.userAgent.indexOf("Mozilla/2.01")
!= -1 ||
navigator.userAgent.indexOf("Mozilla/2.02")
!= -1) {
version
= 2;
}
else
version = 2;
}
else {
version = 1;
}
function which_one(){
if (version ==
4) return "Netscape Version 3.0 for Macintosh.";
if (version ==
3) return "Netscape Version 3.0.";
if (version ==
2) return "Netscape Version 2.x.";
if (version ==
1) return "Microsoft Internet Explorer 3.0.";
}
function change_button() {
document.images[1].src
= active.src;
setTimeout( "document.images[1].src
= inactive.src", 2000);
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR = "#FFFFFF" TEXT = "#000000"
LINK = "#B8860B" ALINK = "#8B0000" VLINK =
"#B8860B">
<A HREF = "http://www.gis.net/~carter/therest/tip_week.html">
<IMG BORDER = 0 VSPACE = 5 HEIGHT = 137 WIDTH = 172 SRC = "../../menus/tip_week.gif"
ALT = "JavaScript Tip of the Week"></A>
<BLOCKQUOTE>
<FONT SIZE = 4>for June 24, 1996: Part 1. Determining Which
Browser is Being Used</FONT>
<BR><BR><BR>
<SCRIPT LANGUAGE = "JavaScript">
if (version ==
3 || version == 4) {
document.write("<A
HREF = \"JavaScript:alert(\'You are using \' + which_one\(\)\)\"
onMouseOver = \"change_button\(\);return true\"><IMG
HEIGHT = 42 WIDTH = 105 BORDER = 0 SRC = \"test_inactive.jpg\"></A><BR>"
+ "<BR><BR><BR>Try moving the mouse over
the \"Test\" button, then click. As you can see, the
button changes color, I\'ll show you <A HREF = \"part02.html\">how</A>
this is done later on. " + "But that\'s not the point.
Normally, if you were using Netscape 2.x, you would have gotten
a whole bunch of error messages " + "when you moved
the mouse over the button.");
}
else {
document.write("<A
HREF = \"JavaScript:alert(\'You are using \' + which_one\(\)\)\"><IMG
HEIGHT = 42 WIDTH = 105 BORDER = 0 SRC = \"test_active.jpg\"></A>"
+ "<BR><BR><BR>If you have Netscape 3.0
the \"Test\" button changes color when the mouse is
moved over it." + " But since you don\'t have 3.0, you
should have gotten a bunch of error messages instead. ");
}
</SCRIPT>
The code checks the browser and platform. If the user is running
various versions of Netscape 3.x, two images are instantiated
and defined with this code:
active = new Image(105, 42);
active.src = "test_active.jpg";
inactive = new Image(105, 42);
inactive.src = "test_inactive.jpg";
For lucky users with one of the favored versions of Netscape,
the inactive GIF is presented with a mouseOver
method associated with it. If the users pass their mouse over
the test_inactive.jpg image,
the function change_button
is called, which has these two source lines:
document.images[1].src = active.src;
setTimeout( "document.images[1].src = inactive.src",
2000);
The confusion dies down as you notice that the function is setting
the first GIF on the page (the Test
GIF) to its active counterpart and then setting a 2000-millisecond
(two-second) delay before the document reverts to the inactive
original setting. If you look at the HTML in the <BODY>
section again, you see the JavaScript If
... test checking the user's browser version. The
unsupported onMouseOver function
is bypassed if the browser cannot support it. Notice in passing
how long the document.write
code lines can get; they are outputting long strings of concatenated
HTML. The concepts presented here are clever; they avoid runtime
errors for unsupported browsers. There's even a check for the
Macintosh operating system. This is a step back from open, distributed
computing, however. We're reverting to a tower of Babel, where
intra-operating system version numbers have to be checked because
the scripting language isn't backward compatible and its feature
set is under proprietary development. Furthermore, how will new
operating systems handle this code a year or two down the line?
New Web browsers? New versions of existing Web browsers? There
is no need to stress the point that nonstandard avenues of development
will remain oddments and curios.
Fahrenheit-to-Celsius Converter
Let's conclude this section by looking at a feature of JavaScript
that came about in Netscape 3.0 beta 5: the capability to evaluate
JavaScript expressions on the right side of an HTML name/value
attribute pair. As the release notes say, "this allows the
attributes of one HTML element to depend on information about
previously placed elements on the page." This interesting
capability to set up codependency between form elements is shown
in James Thiele's neat little Fahrenheit-Celsius Converter JavaScript.(See note)
Listing 23.4 shows James' code. This code is for a Fahrenheit-to-Celsius
converter, using the eval
function by James Thiele (http://www.eskimo.com/~jet/javascript/convert.html).
Listing 23.4. A JavaScript Fahrenheit-to-Celsius converter.
<html>
<head>
<title>Fahrenheit <-> Centigrade Temperature Conversion</title>
</head>
<body>
<P>
<h1>Temperature Conversion:</h1>
</P>
Enter a number in either field, then
<ul><li>click outside the text box, or
<li>press the tab key.
</ul>
<form>
F: <input type="text" name="F" value="32"
onChange="eval('C.value = ' + this.form.C_expr.value)">
<input type="hidden" name="F_expr"
value="(212-32)/100 * C.value + 32 ">
<br>
C: <input type="text" name="C" value="0"
onChange="eval('F.value = ' + this.form.F_expr.value)">
<input type="hidden" name="C_expr"
value="100/(212-32) * (F.value - 32 )">
<br>
<input type=reset name=reset value=reset>
</form>
Notice how the form has two hidden values corresponding to the
Celsius-to-Fahrenheit conversion formula and vice versa. When
the user changes the Celsius or the Fahrenheit value, the onChange
method is called and the eval
function recalculates the values with the conversion formulas.
Figure 23.5 shows the simple user interface.
Figure 23.5 : The Fahrenheit and Celsius input boxes update each other if either one is changed.
Note that this application, of course, is completely tied to the
browser release. In most large firms, it is difficult to upgrade
all users simultaneously on minor or even major version changes,
so a production application of recent JavaScript functions would
be most problematic, even in an all-Netscape environment.
An
Introduction to VBScript
VBScript, Microsoft's answer to Netscape's JavaScript,
looks at an HTML page very much like its rival. It can be embedded
in the <HEAD> or the
<BODY> portions of
the page. If it refers to specific form objects, however, it must
follow the <BODY> tag.
One cosmetic difference is that VBScript code terminates with
a carriage return or a colon (:) character, whereas JavaScript
terminates with a semicolon (;). VBScript, like JavaScript, is
object-based (not truly object-oriented); there are hierarchies
of classes, properties, and methods. This <HEAD>
script sets the foreground color of the document to white and
the background to black, for example:
<HEAD><TITLE>VBScript Colors</TITLE>
<SCRIPT language="VBScript">
<!--
document.bgcolor = "#000000"
document.fgcolor = "#ffffff"
-->
</SCRIPT></HEAD>
VBScript has no strong data typing. All variables (both string
and numeric) fall into a single bucket, or variant, and
it's up to the programmer to apply type-conversion functions as
needed. For example, if I say
mynum = 10
mytext = "abc"
then
Mymixture = cstr(mynum) + mytext
yields the expected result, 10abc.
As with Visual Basic, VBScript distinguishes procedures (parameterized
blocks of code that cannot return data) from functions (also parameterized,
but they can return data).
Microsoft is in a fast-paced war with Netscape to extend VBScript;
every new release of Internet Explorer sees new capabilities of
VBScript. The same objections apply; the development direction
has distinctly proprietary overtones and rival browsers do not
have very good chances at interpreting the latest and greatest
VBScripts.
VBScripts and Security
VBScript has no real underlying security model. It's a subset
of the Visual Basic programming tool, and the Web clients trust
that Microsoft has removed the dangerous elements of the language
to avoid malicious embedded VBScripts. Microsoft has proposed
a code-signing initiative that first was implemented in Internet
Explorer 3.0 Beta 2, however. At least the client is warned when
an unknown control is being transported from the server to the
client. The implication is that, over time, clients will view
certain vendors as trusted software developers and accept their
signed code. Any model of distributed trust is quite shaky, however,
and it's much too soon to evaluate how effective or useless it
might be in the long run.
VBScripts and Interoperability
Microsoft has done some interesting work to position Internet
Explorer (IE) as an extensible program that contains a scripting
engine. The idea is that the engine does not need to know a specific
scripting language in advance. Thus, IE theoretically can be configured
to run JavaScript as well. In practice, though, JavaScript often
runs imperfectly or does not run in IE. This is not surprising
because the competing vendors have no incentive to collaborate
on script enhancements. Any given JavaScript addition to IE therefore
might well be out of date soon after it is implemented. The comfort
level of supporting VBScript pages on a production basis is again
low, just as it is with JavaScript, in a corporate environment
with a multiplatform client base. It is true that VBScripts can
be masked with HTML comment lines to minimize severe runtime problems;
in that case, the noncompliant browsers merely should ignore the
embedded code.
Tip
Neither JavaScript nor VBScript can be positioned to deliver production-grade applications in a corporate multiplatform environment. Their proprietary nature and their quirky behavior across vendor browsers makes them interesting tools that lack
robustness. Java, a networked programming language with a proven security model and support in both UNIX and Microsoft operating system kernels, is preferable for a large-scale production rollout.
VBScript Sample Applications and Code Discussion
This section steps through some introductory VBScript applications
to get a feel for how VBScript can be used to validate forms without
server involvement, perform a simple conversion, and embed a Visual
Basic control.
Simple Client-Side Form Validation
Often in a Web transaction, the user mistypes an entry. Usually,
a CGI process must detect the error and waste bandwidth sending
the bad data back to the client.
My first example shows the efficiencies gained from client-side
validation. The users are meant to type in the number of pounds
they weigh. The first validation step is to check that the input
is numeric. After that hurdle is passed, the numeric range is
checked; the input range, in this case, is set to between 20 and
2,000 pounds.
Figure 23.6 shows the result of an input in excess of 2,000 pounds.
Figure 23.6 : The user's input exceeds the maximum, and VBScript pops up on alert box. The server is not contacted.
A similar validation check catches input that is less than 20
pounds. If all goes well, the program converts American pounds
to the British stone measurement system; one stone is equal to
14 pounds and only the remainder in pounds is stated. Therefore,
someone weighing 100 pounds can be said to weigh "7 stone
2" (7¥14 = 98; 98 + 2 = 100).
Figure 23.7 shows the result of a successful entry (numeric, and
within the range of 20 to 2,000).
Figure 23.7 : The user's valid input of 142 pounds is converted to 10 stone 2.
Listing 23.5 shows the VBScript that converts pounds to stones.
It illustrates a Visual Basic subroutine, form handling, numeric
type checking, and simple functions as well. It also shows, in
passing, the int function
(to take the integer portion of an expression), the mod
function (or modulus, to take the remainder of a division),
and the type-conversion functions Cint
(to integer) and CStr (to
string).
Listing 23.5. VBScript Pounds-to-Stones converter.
<HTML>
<!-- Visual Basic Script Simple Demo Mark Ginsburg 7/96 -->
<SCRIPT LANGUAGE="VBScript">
Sub ptostone()
Dim myform
Dim mypounds
Set myform = document.frmMain
if isnumeric(myform.pounds.value) then
else
msgbox "no good " & myform.pounds.value
exit sub
end if
mypounds = CInt(myform.pounds.Value)
If mypounds < 20 Then
MsgBox "Are you old enough to type?"
Exit Sub
Else
if mypounds > 2000 then
MsgBox "I did not know
elephants could type!"
Exit Sub
End If
End If
stone = sconvert(mypounds)
chstone = CStr(stone)
poundsleftover = pconvert(mypounds)
chlb = CStr(poundsleftover)
MsgBox "You weigh " & chstone & " stone
" & chlb & " pounds."
End Sub
Function sconvert(arg)
sconvert = int(arg / 14)
End Function
Function pconvert(arg)
pconvert = arg mod 14
End Function
</SCRIPT>
<!-- Regular HTML Begins Here - A Simple Form -->
<H2> Pounds to Stone </H2>
<HR>
<FORM NAME=frmMain>
Enter your weight in Pounds ==> <INPUT NAME=pounds TYPE=TEXT>
<INPUT TYPE=BUTTON NAME=btnPounds Value="How many pounds?"
onClick="ptostone()">
</CENTER>
</FORM>
</HTML>
-
Note how, as with JavaScript, the VBScript has a distinct object-based
feel to it. I assign the variable myform
to the form presented in the HTML, and I have immediate access
to the values and variables of that form. I perform the isnumeric
check on the input; if it is OK, I go ahead and do a type conversion
using the CInt function to
perform numerical comparisons. Note how, in VBScript, function
names are the same as the variables that return the value. After
I've figured out the stone corresponding to the valid input, I
output the answer in a MsgBox
dialog box.
Drawing a Chessboard
The next application shows how to use VBScript to create a two-dimensional
chessboard and uses interesting extended HTML table attributes
to manipulate foreground text in a table cell and background cell
color. It colors the squares appropriately and numbers them from
1 to 64.
Figure 23.8 shows the output of the program.
Figure 23.8 : A VBScript to output an array as an HTML table. Extended table attributes color the cell background and cell text.
Listing 23.6 shows the code for the chessboard program.
Listing 23.6. The chess.htm
program.
<HTML>
<HEAD>
<TITLE>My Beautiful Chessboard</TITLE>
</HEAD>
<BODY>
<h1> My Beautiful Chessboard </h1>
<SCRIPT LANGUAGE="VBScript">
<!--
Dim X
Dim Y
WHITE = "ffffff>" ' this strange >
becomes clear in the concatenation code below
BLU = "0000ff>"
colornum = " " '
define this as a string
sqcolor = " "
Dim CArray(8, 8) ' a 2-dimensional array
for the square numbers.
document.write "<CENTER>"
document.write "<TABLE border=4 padding=2>"
'
' The only trickiness is the mod (modulus) operator: if
' the array number minus the row number is odd, then
make
' the square color black; otherwise make it white.
'
' Also: make use of FONT COLOR tag to set
color of text
' within
a Table Cell; make use of <TD BGCOLOR...
' tag to
set the background color of the Table Cell.
For X = 1 to 8
For Y = 1 to 8 ' fill in the
values of each square
CArray(X,Y) =
((X - 1) * 8) + Y
if ((CArray(X,Y)
-X) mod 2 = 1) then
sqcolor = "000000"
colornum = "<font color=#" & WHITE & CStr(CArray(X,Y))
& "</font>"
else
sqcolor = "ffffff"
colornum = "<font color=#" & BLU & CStr(CArray(X,Y))
& "</font>"
end if
document.write "<TD bgcolor=#" & sqcolor &
">" & colornum & "</td>"
Next
document.write "<tr>" ' must advance
to next row
Next ' out of loop, just finish up the HTML.
document.write "</TABLE>"
document.write "</CENTER>" & "<hr>"
document.write "Next: write a chess-playing program."
-->
</SCRIPT></BODY></HTML>
The code demonstrates a double For
loop to create the 8¥8 chessboard.
It then does some arithmetic to figure out the appropriate number
for each square and uses the modulus operator (mod)
to color the background of the odd-numbered squares black and
the even-numbered squares white. Similarly, the foreground number,
which is written on the square, is logically set to white if it's
on a black square and blue if it's on a white square. Not all
browsers support these advanced table attributes, but as you see
in Figure 23.8, it's no problem for Microsoft Internet Explorer.
Fahrenheit to Celsius Revisited: Using ActiveX Controls
VBScript has another strategic advantage that Microsoft is leveraging
heavily: it can embed objects that were defined by developers
taking advantage of Microsoft's ActiveX controls.(See note)
These controls, which can be quite sophisticated, are assigned
unique class IDs automatically by the tool that created them (the
Internet Control Pack extension to Visual Basic), and their attributes
can be altered by the VBScript. The ActiveX Control Pad utility(See note)
is another handy way of generating object tags, CLSIDs, and parameter
tags. The developer just needs to alter the parameter values to
change the appearance of the control on-screen.
Listing 23.7 shows an example of a VBScript application, (See note)
again a Fahrenheit-to-Celsius converter, taking advantage of a
scroll control and label controls.
Listing 23.7. The scroll.html
application.
<BASE HREF="file:///C|/ActiveX
Samples/scroll.html">
<HTML>
<HEAD>
<TITLE>VBScript Temperature Converter</TITLE>
</HEAD>
<CENTER>
<H3>VBScript Temperature Converter</H3>
<HR>
<OBJECT ID="LabelF" WIDTH=97 HEIGHT=23
CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0">
<PARAM NAME="PicturePosition"
VALUE="524294">
<PARAM NAME="Size" VALUE="2046;494">
<PARAM NAME="FontEffects"
VALUE="1073741825">
<PARAM NAME="FontHeight"
VALUE="240">
<PARAM NAME="FontCharSet"
VALUE="0">
<PARAM NAME="FontPitchAndFamily"
VALUE="2">
<PARAM NAME="ParagraphAlign"
VALUE="3">
<PARAM NAME="FontWeight"
VALUE="700">
</OBJECT>
<OBJECT ID="ScrollBar1" WIDTH=23 HEIGHT=165
CLASSID="CLSID:DFD181E0-5E2F-11CE-A449-00AA004A803D">
<PARAM NAME="Size" VALUE="494;3493">
<PARAM NAME="Min" VALUE="-1000">
<PARAM NAME="Max" VALUE="1000">
</OBJECT>
<OBJECT ID="LabelC" WIDTH=97 HEIGHT=23
CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0">
<PARAM NAME="Size" VALUE="2046;494">
<PARAM NAME="FontEffects"
VALUE="1073741825">
<PARAM NAME="FontHeight"
VALUE="240">
<PARAM NAME="FontCharSet"
VALUE="0">
<PARAM NAME="FontPitchAndFamily"
VALUE="2">
<PARAM NAME="ParagraphAlign"
VALUE="3">
<PARAM NAME="FontWeight"
VALUE="700">
</OBJECT>
</CENTER>
<SCRIPT LANGUAGE="VBS">
Sub ConvTemp()
Dim CTemp
CTemp = CInt((ScrollBar1.Value - 32) *
(5 / 9)) ' Celsius Value
LabelF.Caption = CStr(ScrollBar1.Value)
& " F" ' Scroll
Value is Farenheit
LabelC.Caption = CStr(CTemp) & "
C"
End Sub
Sub ScrollBar1_Scroll()
ConvTemp()
End Sub
Sub ScrollBar1_Change()
ConvTemp()
End Sub
</SCRIPT>
<BODY onLoad="ConvTemp">
</BODY>
</HTML>
The actual logic is very simple; the bulk of the code is to set
up the objects and their parameters. When the user moves the scroll
slider, the function ConvTemp()
is called and the two labels, corresponding to the Fahrenheit
and Celsius values, are recalculated. Figure 23.9 shows one instant
in time of this application.
Figure 23.9 : A scroll object is embedded on an HTML page.
Embeddable objects inside HTML are a recent focus of the World
Wide Web Consortium (W3C) and Microsoft has changed its CLSId
syntax to conform with W3C guidelines. It will be interesting
to see how Microsoft markets its VBScript applications and its
vision of embedded objects to the W3C standards body.
Client-Side
Scripting Check
Both JavaScript and VBScript offer interesting
expressive possibilities, advancing the role of the client in
Web transactions.
Don't confuse JavaScript with Sun Microsystems'
Java-the robust, fully object-oriented network programming language.
Developers must be aware that support
across operating systems, Web browser vendors, and even Web browser
versions will be spotty for each of these tools. This stems from
the proprietary nature of the initiatives.
Netscape and Microsoft both face interesting
challenges to sell these products to a skeptical Internet open
standards community.
Runtime interpreted scripting languages,
such as VBScript and JavaScript, have no security model to speak
of. The end user assumes that the builders do their best to disallow
dangerous operations. In the absence of a larger, encompassing
network security scheme, this assumption either suffices or is
inadequate on a case-by-case basis.
Footnotes
Larry Masinter pointed out this interesting paradox
at the fifth World Wide Web Conference, Paris, France, May 1996.
A synopsis of Loverso's creative
attacks can be found on-line at http://www.osf.org/~loverso/javascript/track-me.html.
Many thanks to Paul Colton for
liberal use of his JavaScript code, courtesy of Live Software.
Look for Paul's book, Java Unleashed, published by Sams.net.
All code samples at Paul's site, http://jrc.livesoftware.com/,
have been updated to work with Netscape 3.0.
Thanks to Nick Heinle for providing
this interesting code for discussion. His JavaScript Tip of the
Week site is located at http://www.gis.net/~carter/therest/tip_week.html.
Thanks to James Thiele; his application
is on-line at http://www.eskimo.com/~jet/javascript/convert.html.
More information is available
at http://www.microsoft.com/activex/controls/,
and information on general Microsoft Internet initiatives can
be found at http://www.microsoft.com/intdev/.
Microsoft's on-line Visual Basic reference guide is at http://www.microsoft.com/vbscript/us/vbslang/vbstoc.htm.
Information on the ActiveX Control
Pad is at http://207.68.137.35/workshop/author/cpad/.
Thanks to Joe La Valle for the
Temperature Scrollbar Visual Basic application code.
Wyszukiwarka
Podobne podstrony:
ch23 (18)ch23ch23ch23Ch23 pg753 774RM ch23CH23 (5)ch23ch23 (3)CH23 (14)ch23ch23 (11)ch23ch23 (9)więcej podobnych podstron