Dynamic Web Pages

try clicking on the pluses!
+ the beginning
+ the middle
+ the end
The web pages we've created up to this point have been static webpages, meaning that nothing on the page changes. You only see different content by loading different webpages. Moreover, everyone looking at that page sees exactly the same thing. All but the most basic sites these days have dynamic content, which means that user interactions can cause changes to the current page, or that websites have pages that look different to different users. Fancy websites like google-maps are built around the idea of dynamic web content. To the right is a silly example of a simple piece of dynamic content. Click on the +'s and -'s and see what happens. Note that the URL never changes.

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.

  1. Allowing code to execute in response to user input (or other events, like a timer going off) could pose a security risk. In client-side scripting the one visiting the website incurrs risk. In server-side scripting the organization hosting the website incurrs risk.
  2. Executing scripts costs CPU cycles. Server-side scripts cause more work for the server machine, client-side scripts cause more work for the client-side machine.
  3. Client-side scripts don't require network communication to change what's on the webpage. Server-side scripts can only change what the user sees after some back-and-forth message passing between server and client.

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.

Embedding Scripts and the DOM (Document Object Model)

The World Wide Web Consortium (W3C) is an organization that is responsible for the development of many standards for the web. HTML is one of those standards. The W3C has a lot of nice tools for learning about HTML and related standards. You can read their material on the DOM starting here.
Browsers allow you to embed scripts in HTML code, as you've already seen, using the
<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.

One thing you have to think about when you have embedded scripts is when each script will get executed.
Essentially, they get executed in the order the browser comes across them.

Hopefully the following example clarifies this:
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 .

Embedded scripts with Javascript code in separate files

For larger scripts, or for Javascript code you want to use in many pages, it's nice to keep the Javascript code in a separate file. This is done by setting the 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.

More of the DOM: document.location

Input a Javascript expression or statement and press enter
js>
Another feature of the DOM that we can manipulate with Javascript code is the value 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>
If you hover over the link, you look like you're going one place (ex3.html), but then you appear to be sent to another. What happened? Well, you actually do go to ex3.html. However, that page immediately redirects you to http://www.usma.edu.

A timely script

Here's an example of the kind of thing we can do with embedded scripts:
Every time you visit this page, you get an updated report of the time remaining 'til graduation. Kind of a big number, eh?

99 Bottles of Beer

Check out 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.

A timely script, Version 2

Allright, clearly the graduation clock should actually tick, so here it is:
This goes a bit beyond what I intend to cover in the course, but you can "View Source" on it, and probably figure it out for yourself. After the next lesson, most of it should make sense ... except for the 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.

HTML and e-mail

Most e-mail clients allow you to write and read e-mails with HTML formatting, not just plaint-text. Combining this with Javascript allows for some evil possiblities. For example, we know how to make HTML automatically send you to the page of our choosing, no clicks required! If an e-mail client executes Javascript embedded in an HTML-formatted e-mail, we can craft an e-mail such that just opening the e-mail sends the machine's browser to a site of our choosing. You are safer with an e-mail client that does not execute embedded Javascript like this!

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.