///Get Dynamic Web Content with HTTPRequest

Get Dynamic Web Content with HTTPRequest

A refreshing approach to page refreshes

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.

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:

Property       Value

readyState State of the document
status HTTP response code
responseText Document as a string
responseXML Document as XML
Methods                                      Value 

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>  
<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

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

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.

• Peruse the Developer Bookstore to find a plethora of titles to help you work better.

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

2010-05-26T11:38:17+00:00 April 11th, 2005|Java|0 Comments

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. Contact Doug at dug [at] us.ibm.com.

Leave A Comment