Previous Page
Next Page

Hack 21. Submit Hidden Tag Values to a Server Component

Send the values of hidden form fields to the server whenever you want.

The use of hidden form fields to connect one request from the same user to another may be less compelling these days, as newer approaches (such as cookies and sessions) have evolved. However, your application might have other reasons for using an <input type="hidden"> element.

A hidden field contains a value that users do not see, unless they peek at the page's source code. It can be used to send the server some extra identifying information along with the rest of the form input.

Unless the server specifies with various HTTP response headers that a web page shouldn't be cached, the browser will cache, or keep a local copy of, each page a user requests. The purpose of this caching strategy is to improve performance and prevent unnecessary network requests for the same page if it hasn't changed. But what if you want to track the number of times a user opens up a page, even if the page derives from that user's client-side cache. This hack sends a server component the value of a hidden input field whenever the page is loaded into a browser, letting it know when the page is loaded from the cache as well as when it is downloaded from the server.

You could use such a strategy for web user testing within an application. However, you would probably bombard a network with many wasteful requests if you included this feature in a production application. In addition, any kind of automated submission of this nature could raise privacy issues with web users or violate online privacy policies. This type of web-application behavior should be checked against user expectations and site policies before it is ever used in a production site.


The HTML for the web page in this hack is minimal, but it includes a hefty hidden value tucked inside of it. The value of the hidden field is dynamically generated when the browser loads the page. Here's the code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<html xmlns="" xml:lang="en" lang="en">
    <script type="text/javascript" src="js/http_request.js"></script>
    <script type="text/javascript" src="js/hacks2_11.js"></script>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>hidden hacks</title>
<h3>Delving into some navigator properties</h3>
<div id="content">
These include:   navigator.appName, navigator.platform, 
navigator.language, and navigator.userAgent.
<form action="javascript:void%200">
    <script type="text/javascript" src="js/innerInput.js"></script>

When the page is loaded into the browser, the JavaScript file innerInput.js dynamically creates a hidden input tag and populates that tag with useful information, such as the name of the page, when it was accessed, the computing platform of the user, the default language for the browser, as well as the User Agent string associated with the user's browser. Code can access most of these properties via the navigator client-side object in JavaScript. For example, accessing navigator.platform returns MacPPC for my computer; navigator.userAgent provides the content of the User Agent request header from my browser.

Now the hidden tag has a lot of meaningful information for its value attribute. inner_input.js contains:

var delim = ":::";
        "<input type=\\"hidden\\" id=\\"hid\\" name=\\"data\\"  value=\\""+
        location.pathname+delim+new Date(  )+
        delim+navigator.language+delim+navigator.userAgent+"\\" />"); 

The document.write( ) method can dynamically write part of the page as the browser loads the HTML. The code creates a hidden tag with the id hid. The user does not see the value of this tag, but the value is available to JavaScript code. The values of the various properties (navigator.userAgent, etc.) are separated by the characters :::. For example:

Thu Oct 27 2005 10:37:15 GMT-0400:::
Netscape:::MacPPC:::en:::Mozilla/5.0 (Macintosh; U; 
PPC Mac OS X; en) AppleWebKit/412.6 
(KHTML, like Gecko) Safari/412.2

Notifying Home

Now we want to send this information to a server, so it can be logged. For this task, the application requires more JavaScript. The page imports (with script tags) two more JavaScript files. http_request.js (see "Use Your Own Library for XMLHttpRequest" [Hack #3]) sets up the request object to talk with the server. hacks2_11.js contains the code that accesses the input tag's value and sets up a request to POST it to the server as soon as the browser loads the page:

window.onload=function(  ){
    var hid = document.getElementById("hid");
    var val = "navprops="+encodeURIComponent(hid.value);
    url = "";
    httpRequest("POST",url,true, handleResponse,val);
//event handler for XMLHttpRequest
function handleResponse(  ){
        if(request.readyState == 4){
            if(request.status == 200){
                //commented out now: alert(
                //"Request went through okay...");
            } else {
                //request.status is 503
                //if the application isn't available;
                //500 if the application has a bug
                        "A problem occurred with communicating between"+
                        " the XMLHttpRequest object and "+
                        "the server program.");
        }//end outer if
    } catch (err) {
        alert("It does not appear that the server "+
              "is available for this application. Please"+
              " try again very soon. \\nError: "+err.message);


The code gets the value of the input element and encodes the value's characters so that they can be properly transferred over the network. The code then sends a POST request because of the volume of this server message.

A GET request appends the parameters to the end of the URL, whereas a POST request sends the parameter data as a block of characters following the request headers.

The httpRequest( ) function is a wrapper around the code that sets up an XMLHttpRequest object and sends the message.

The httpRequest( ) function does a browser compatibility check [Hack #1]. This function also checks for any data that is designed to be posted. This data will appear as the fifth parameter to the function.

JavaScript allows code to define a function, and client code may then pass variable arguments to the function. These parameters can be accessed within the defined function as part of an arguments array, which every JavaScript function has built in. Therefore, arguments[4] represents the fifth parameter passed into a function (the array is zero-based).

http_request.js uses the request object's setRequestHeader( ) function to convey to the server component the content type of the sent data:

        "application/x-www-form-urlencoded; charset=UTF-8"); 

The HTTP POST request will not succeed with Firefox, for instance, unless you include this request header (see "Use the Request Object to POST Data to the Server" [Hack #2] for details).


The server component can log the posted data, or do whatever the application calls for. Here is an example log entry after a couple of requests with Firefox and Safari (with some of the logged text removed and/or edited for readability):

Thu Oct 27 2005 10:37:15 GMT-0400:::
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412.6 
(KHTML, like Gecko) Safari/412.2

Thu Oct 27 2005 10:49:24 GMT-0400 (EDT):::
Netscape:::MacPPC:::en-US:::Mozilla/5.0 (Macintosh; U; 
PPC Mac OS X Mach-O; en-US; rv:1.7.12) 
Gecko/20050915 Firefox/1.0.7

You can see that the name of the file is included, followed by the date and time when it was requested, then some browser-specific data such as the default locale (en-US, or U.S. English) and the value of the User Agent request header.

In JavaScript, the User Agent header data is accessed from the navigator.userAgent property.

Previous Page
Next Page