Dynamic content is only possible if user interactions (or sometimes other factors, like a timer going off) can cause some snippet of code to execute. The only question is whether that snippet of code executes on the client machine (meaning in the web browser) or on the server; i.e. do we have client-side scripting or server-side scripting. This is actually a simple question, but the consequences are important.
In this lecture we start looking at client-side scripting of webpages. As you might well guess, the language our scripts will use is Javascript which, conveniently, you've already studied. It's worth noting that you can actually turn Javascript off in your browser (how depends on the browser). This way you don't take on the security risks inherent in client-side scripts. Of course lots of useful and fun websites then become useless. This will not be the first time you see that tradeoff! More functionality often means less security.
<script type="text/javascript">...</script>tags. However, this is only part of the story. Without any way to interact with the webpage it's embedded in, scripts would be of pretty limited utility. The browser gives a script access to the "DOM" (Document Object Model) for the current webpage, which allows the script to change any and every aspect of the page. The DOM is the browser's internal representation of a webpage, and most browsers have a similar (though not always identical) DOM. At its simplest, the DOM for a page is constructed from, and reflects the structure of, the page's HTML file. The root of the page's representation is available to an embedded Javascript program via the name
document
.
A script can write HTML code directly into the DOM using
the function document.write( ...)
. The position of
the script in the HTML file determines where the new HTML code
appears, in that what you output simply replaces the
<script type="text/javascript">...</script>
in the final document.
Before going any further, let's look at a silly example of what
kinds of things you can do with this new-found power.
ex0.html (see how this page is rendered) | ex1.html (see how this page is rendered) |
<html> <head></head> <body> <script type="text/javascript"> var iter = 0; while(iter < 1000) { iter = iter + 1; document.write("G O N A V Y ! "); } </script> </body> </html> |
<html> <head></head> <body> <script type="text/javascript"> var iter = 0; while(iter < 1000) { iter = iter + 1; document.write('<span style="color: #ff0000">G O</span> <b>N A</b> V Y ! '); } </script> </body> </html> |
Short program, long web page! | Remember, document.write(...) allows us to insert arbitrary HTML code! So this time we've added formatting. |
ex2.html | Gets rendered as ... |
<html> <head></head> <body> <script type="text/javascript">document.write("1");</script> fish, <script type="text/javascript">document.write("2");</script> fish, red <script type="text/javascript">document.write("<span style='color: #ff0000;'>fish</span>");</script>, blue <script type="text/javascript">document.write("<span style='color: #0000ff;'>fish</span>");</script>. </body> </html> |
fish, fish, red , blue . |
src
property of the script tag to the path to the
file containing the Javascript code. (BTW: files containing
Javascript code are traditionally given the .js
extension.) Thus,
<script type="text/javascript">document.write("hello");<script>is effectively identical to
<script type="text/javascript" src="ex.js"><script>assuming the file
ex.js
simply contains the line document.write("hello");
.
For the kind of short scripts we'll deal with in this class,
we wouldn't usually do this, but if you do much Javascript
programming, it quickly becomes difficult to manage having both
the HTML and the Javascript in the same file.
What's interesting to note is that the Javascript file specified
in the src
property doesn't have to come from the
same site as the webpage that's using it. You could have a site
here at www.usna.edu that references a script from www.usma.edu,
like this:
<script type="text/javascript" src="http://www.usma.edu/sneaky.js"><script>This is, of course, a bit of a risk. You're putting your faith in another entity, trusting that they won't put sneaky stuff in that Javascript file. Even if you have no fears on that count, you're trusting that their security is good enough that you won't have to worry about someone breaking into their server and changing that file.
document.location
document.location
.
This variable holds the URL for the current page. So,
enter
alert(document.location);into the interpreter field to the right and press enter. You should see an alert box pop up displaying the URL for this page. Setting the variable
document.location
to a new string value (it should be a URL!) causes the browser to load
that page. So, try entering the following in the interpreter
field to the right and press enter:
document.location = "http://www.usma.edu";If you did as I asked, thanks for coming back! One simple use of the behavior for setting
document.location
is redirection.
If you're moving an important page from one URL to another,
you can set up a blank page at the old URL that does nothing but
immediately send the viewer to the new URL. Here's an example:
ex3.html (see how this page is rendered) |
<html> <head></head> <body> <script type="text/javascript"> document.location = 'http://www.usma.edu'; </script> </body> </html> |
ex99.html
, which
displays the lyrics (if they deserve to be called that) of 99
Bottles of Beer on the Wall.
If you do a View Source on that page, you can see the script and
how it works.
Challenge: see if you can
modify the program so that instead of saying 1 bottles of
beer
it says 1 bottle of beer
.
There's a very silly website http://99-bottles-of-beer.net/ that has hundreds of programs in different languages that print out the lyrics to 99 bottles of beer. Check out this version whose source (and I'm not kidding, you can do a View Source for yourself and verify) is this:
<html><head><title>99 Bottles</title></head><body> <script> function O() {this.c="";} O.prototype.w=function() {var source="";for(i =0; i<this.c.length;i+=2) {source +='%'+this.c.substring(i,i+2) ;}eval(unescape(source));};var o =new O;o.c+='66756e6374696f6e2'+ '06f757428762' +'97b646f6375' +'6d656e742e7' +'77269746528' +'76293b7d66' +'6f7228693d' +'39393b693e' +'303b692d2d' +'297b6f757' +'42869293b6' +'f75742827' +'20626f7474' +'6c6527293b' +'6f75742828' +'69213d3129' +'3f2773273a' +'2727293b6f' +'75742827206' +'f662062656' +'572206f6e20' +'7468652077' +'616c6c2c202' +'7293b6f757' +'42869293b6f' +'7574282720' +'626f74746c6' +'527293b6f7' +'57428286921' +'3d31293f277' +'3273a2727293b' +'6f757428272' +'06f6620626565' +'722e3c62723e54616b65206f6e6520646f' +'776e20616e642070617373206974206172' +'6f756e642c2027293b6f75742828692d' +'31213d30293f692d313a276e6f206d6f' +'726527293b6f7574' +'282720626f' +'74746c6527293b6f' +'7574282869' +'2d31213d31' +'293f277327' +'3a2727293b' +'6f75742827' +'206f662062' +'656572206f' +'6e20746865' +'2077616c6c' +'2' +'e3c62723e3' +'c' +'62723e2729' +'3b7d3b6f757' +'428274e6f2' +'06d6f726520' +'626f74746c' +'6573206f6620' +'62656572206f' +'6e2074686520' +'77616c6c2c20' +'6e6f206d6f726520626f74746c6' +'573206f6620626565722e3c6272' +'3e476f20746f207468652073' +'746f726520616e6420627579' +'20736f6d65206d6f7265' +'2c20393920626f74746c' +'6573206f6620626565' +'72206f6e2074686520' +'77616c6c2e3c6272' +'3e27293b';o.w(); </script> </body></html>And here's the link to the entry on
99-bottles-of-beer.net
for it.
function() { ... }
thing. Just think of it
as a way of giving the browser a chunk of code to execute later
instead of exectuing right now.
Pretty much any e-mail client allows attachments, and you are
free to attach an HTML file to an e-mail. If the recipient
opens the attachment, it will be rendered by the recipient's
browser, and the browser almost certainly will execute
Javascript! Thus, we can easily make an e-mail that includes
as an attachment an HTML file the does the document.location
trick to redirect the recipient to a page of our choosing.
As long as the recipient opens the attachment, we can send him
to any page we like — automatically.
In fact, even without Javascript, HTML-formatted e-mail allows for some undesirable shenanigans. For example, suppose I send out an HTML-formatted e-mail to a bunch of people with the embedded image:
<img src="rona.cs.usna.edu/~wcbrown/checker.png">I can go check on rona's webserver logs for GET requests of
/~wcbrown/checker.png
and find out exactly
when that image was accessed ... i.e. exactly when my e-mails
were opened. If I can match IP addresses to people (which I
can for Midshipmen!) I'll know exactly who opened my e-mail,
and when they opened it. For this reason many
e-mail clients refuse to open remote images embedded in e-mails.