Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Get dynamic Web content with HTTPRequest

A refreshing approach to page refreshes

Doug Davis, Architect, IBM, Software Group
Doug Davis is an architect in the Emerging Technologies division of IBM. His previous roles include technical lead of the Emerging Technologies Toolkit, WebSphere Machine Translation, Team Connection, and the IBM Fortran 90.

Summary:  The HttpRequest object initially might not seem like a big deal. Explore the possibilities of it when you issue a HTTP GET or POST on a URL for succinct page refreshes that update only a specific portion of the Web page.

Date:  18 Jan 2005
Level:  Introductory

Activity:  20482 views
Comments:  

This article is for those of you who come across programming features that initially don't seem like such big deals, but in reality, open a vast array of possibilities. I came across such a feature not long ago. Now that I've used it quite a bit, I want to share the little gem with the rest of you. First, a little background: Many times I have put together a Web application and found the traditional way of updating the Web page quite limiting. Typically solutions include:

  • Make the user click F5 to refresh the data
  • Embed some meta-data that automatically refreshes the page after some timeout
  • Use JavaScript and reload the page after some timeout
  • Wait for the user to explicitly click a button or link that does a GET or POST

The main gripe I have with all of these solutions is that the level of granularity of the "get new data" is at the page level. By that I mean each one reloads the entire page -- causing flickering and, in some cases, losing my current scroll position. At times as I read a long document and the refresh occurs, the whole page scrolls and takes me back to the top (yes, I'm going to repeat this a lot because it really bugs me). The other complaint I have is that since each works on the page level I lose any updates I might have made on the page. For example, with any of the above auto-refresh options, when I enter data and click a Submit button, I lose any updates I made to text entry fields prior to clicking Submit.

You might wonder why I don't want to refresh the entire page. Suppose I have a Web page that acts like a portal for a management system. Perhaps, one section of the page displays log entries as they are generated and another section displays the current load on the system. And in a third section is an area where I am examining other data (large amounts of data) which requires that I scroll a lot. If the screen refreshes every minute or so -- it flickers and loses any temporary information -- like entry fields and scrolling positions of sub-elements -- each time.

Are applets healthy?

One obvious solution is to use frames. That would work, but it only solves the visual dependency issue between the various items being displayed. Plus, you can't always break apart your UI into well-portioned areas. Another possibility is to make use of applets and DHTML.

If you use an applet, you can pretty much load any piece of data, at will, from the server and with DHTML, figure out the right chunk of HTML to update. This solution actually provides quite a bit of freedom, and it really does allow a Web page designer an incredible amount of freedom to pass data back and forth between the Web browser and the server. You're no longer limited to the explicit GET and POST operations at the page level. I have one problem with an applet-based solution: it requires -- you guessed it -- an applet. Granted, it's just my personal prejudice, but I don't like the idea of requiring the reader of a Web page to download and install a JVM. Depending on the Web page, it might not be that big of an issue. If the readers are technical folks, then they will probably have one installed anyway. However, if I'm putting together a page that will be viewed by non-technical people who don't know the difference between installing a JVM and installing a virus, I believe that this is a worry they should not have to overcome. The other problem with applets is that the communication is limited to just the server from which the original request originated - a good security feature, but it can be a bit limiting.

So, what's left? A while back I came across a nifty little object that's available to JavaScript programmers (and others) that allows you to do an HTTP GET or POST without any effect on the current Web page itself. This means that at any time, either through a timer or some action taken by the viewer of the page, your JavaScript can send a request to any server or URL and get a response. You can then take the data in this response and do whatever you want with it. Ok, big deal, you think. Well, have a look at what you can now do with this.

Take the scenario I mentioned earlier, in which a Web page is acting as a portal for a management system. In some portlet systems, when a portlet needs to be updated it will refresh the entire page, causing all of the problems I just described. However, you can now do an HTTP GET for just one of those portlets and retrieve the new contents, using DHTML to update those contents without affecting any of the others. On the surface it might not seem like such a huge leap in functionality, but it will by the end of this article. First, though, examine this object.


Along came the HttpRequest object

The HttpRequest object is wonderful in that it does nothing more than allow you to issue a GET or POST on any URL. Look at a subset of its properties and methods:

PropertyValue
readyStateState of the document
statusHTTP response code
responseTextDocument as a string
responseXMLDocument as XML
MethodsValue
open( method, URL, async, user, password )Creates a connection to the specified URL
send( data )Issue the request

Start with the methods and their parameters:

  • For the open() method:
    • The method parameter is the HTTP method (that is, GET or POST).
    • The URL is obvious.
    • The async parameter indicates whether the request is done asynchronously or not. Basically, if not done asynchronously, then the entire browser blocks (or hangs) until the request is finished. Clearly, setting this to true is the preferred way to go.
    • The user and password parameters allow you the option of passing in the authentication information as needed.
  • The send() method actually makes the request.
    • When you do a GET, the data parameter can be null. To send data to the server, that is, do a POST, then you set the data parameter to send the contents of the POST.

Look at the properties:

  • The readyState property represents the state of the document at the URL. You can use this to know when the document has finished loading (more on this in a bit).
  • The status property contains the HTTP response code (for example, 200) after the request is completed.
  • The responseText and responseXML properties contain the document itself, either as a string or as XML. You are free to use either one depending on which is easier for your use.

To look at this in action, examine the sample HTML page in Listing 1:


Listing 1. background.html
  <html>
    <script>
      var xmlDoc = null ;
  
      function load() {
        if (typeof window.ActiveXObject != 'undefined' ) {
          xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
          xmlDoc.onreadystatechange = process ;
        }
        else {
          xmlDoc = new XMLHttpRequest();
          xmlDoc.onload = process ;
        }
        xmlDoc.open( "GET", "background.html", true );
        xmlDoc.send( null );
      }
  
      function process() {
        if ( xmlDoc.readyState != 4 ) return ;
        document.getElementById("output").value = xmlDoc.responseText ;
      }
  
      function empty() {
        document.getElementById("output").value = '<empty>' ;
      }
    </script>
  
    <body>
      <textarea id="output" cols='70' rows='40'><empty></textarea>
      <br></br>
      <button onclick="load()">Load</button> &nbsp;
      <button onclick="empty()">Clear</button>
    </body>
  </html>

If you copy and paste the code in Listing 1 into an HTML file named background.html and bring it up in your browser, you should see a page that looks like Figure 1:


Figure 1.The background.html file as seen in your browser
The background.html file as seen in your browser

When you view the example Web page (background.html) in your browser, click Load. The JavaScript asynchronously (in the background) does a GET of background.html and places the result in the <textarea>, which then looks like Figure 2:


Figure 2.The resulting code
The resulting code from a GET

In examining the code itself, look at the load() function first:


Listing 2. The load() function
    function load() {
      if (typeof window.ActiveXObject != 'undefined' ) {
        xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
        xmlDoc.onreadystatechange = process ;
      }
      else {
        xmlDoc = new XMLHttpRequest();
        xmlDoc.onload = process ;
      }
      xmlDoc.open( "GET", "background.html", true );
      xmlDoc.send( null );
    }

In this function, you create a new HttpRequest object. Notice that the first thing in Listing 2 is an if-statement that figures out whether the browser is Microsoft Internet Explorer or not. If the result of the condition is true, and the browser is Internet Explorer, then you create the ActiveX version of the HttpRequest object; otherwise you assume that the browser is Mozilla and use the built-in XMLHttpRequest object. In either case, you then tell it to call the process() method when the browser finishes loading the page (notice the property is named slightly different depending on the browser). This code works on Internet Explorer 6.0 and Mozilla Firefox 1.0. I make no claim about any other browser or browser version. You then use the open() method to define the HTTP method, URL and the async flag. And finally, you issue the request using the send() method. This method returns immediately, because the async parameter is set to true, allowing normal Web page activity to continue.

When the request for the page is finally completed, the browser automatically calls process() which updates the contents of the <textarea>. It is important to note the first line in process():

   if ( xmlDoc.readyState != 4 ) return ;

This is important is because, depending on which browser you use, it might call the process() method before the URL completely loads. That's why it's imperative to check the status of the document and continue only if it's ready (and shows a value of 4). Once ready, you then update the contents of the <textarea> with the document at the URL you specified -- in this case, the example Web page itself. Hopefully, you can see how with this technique, in combination with DHTML, you can dynamically and asynchronously update portions of a Web page with minimal impact on the reader.


In Conclusion

In my opinion, those couple of lines of code have really expanded the available options. For example, one of the projects I've played with (and hope to make available on alphaWorks or developerWorks) uses this technique to allow multiple people to simultaneously view and edit data on a Web page. Users see updates on their browsers immediately without having to refresh and without any annoying flickering, loss of scrolling position, or loss of unsaved data.

I want to point out one important thing, if it wasn't already obvious, and that is -- this all happens through polling. This means that the browser must request updated data be sent, which is the one downside in comparison to applets. In the applet-based solution, the server can push data out to the browsers whenever it needs to. By using the HttpRequest object, you only get updates upon request so you want to time the polling for new data accordingly; network traffic might be too high otherwise. Of course, you also want to consider not requesting all data, but just changed data each time. Then if nothing has changed, no data is returned -- again, increasing performance. Perhaps it's just me, or I've been living under a rock, but I haven't seen this feature widely used or advertised. I hope you find it as useful as I have.


Resources

  • Read this recommendation from Lotus on updating Web pages with the Refresh agent.

  • See this posting regarding the amount of data that can be sent to a Domino database.

  • In this recent article, the first of a series on FacesClient Components (formerly know as The Odyssey Browser Framework), discover how to refresh pages and not involve the portal page (developerWorks, November 2004).

  • Learn workarounds to data processing redundancy using a browser-based solution in another recent article (developerWorks, November 2004).

  • Download this Configuration Utility for a secure portal from alphaWorks.

  • Avail yourself of developerWorks tutorials designed to take the Web developer step-by-step through a variety of educational sessions.

  • Browse for books on these and other technical topics.

  • Visit both the developerWorks Web Architecture zone and the and Java technology zone for articles covering various Web-based and Java-based solutions, respectively.

About the author

Doug Davis is an architect in the Emerging Technologies division of IBM. His previous roles include technical lead of the Emerging Technologies Toolkit, WebSphere Machine Translation, Team Connection, and the IBM Fortran 90.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Java technology
ArticleID=33220
ArticleTitle=Get dynamic Web content with HTTPRequest
publish-date=01182005
author1-email=dug@us.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers