Creating an ASP-driven Page Counter for HTML Pages

This article examines a technique to provide dynamic content generated from an ASP page onto a
static HTML page. Specifically we needed to display a page counter on a number of static HTML pages.
This article discusses how we accomplished this.

Introduction
My company maintains a Web site for a customer that hosts Web pages for its clients
(i.e. wwww.customer.com/client1.html). A problem we ran into recently with
this site involved its usage of a "Free-WebPage-Counter" service. It seemed
the company providing the counters was going to have to start charging for
them. The fee was going to be assessed on a yearly basis per counter. This
meant if we stayed with this counter service our customer was going to have
to shell out well over a thousand dollars a year just for page hit counters!

We quickly realized that we had a limited number of options. Paying the thousands of dollars for the
simple hit counters was out of the question, so the remaining options we came up with were:

Find another "Free-WebPage-Counter" service. This was the most obvious
solution. To implement this we would simply have to setup our existing hit counters
with a new, free service. However, this would require a modification of all of the pages that had counters,
unfortunately.
We ended up deciding that this was not a viable solution, since there would be no
guarantee that the Hit Counter company we chose to go with would not revoke their free
service after a while, placing us back into the same dilemma we were facing.

Build or get our own CGI counter. This was an option for a while, but we
had little experience with Perl or the like, and did not have enough time
to learn something totally new. We decided that we would like the solution to be
our own, so that ruled out simply cutting and pasting a working CGI hit counter.
Since our Perl skills were weak and we did not feel like snarfing an existing counter,
this option was quickly dismissed.

Use ASP. This would be an optimal solution since ASP has a couple of built-in counter
components. (For more information be sure to read: Using the Counters Object and
Recording Page Hits with Microsoft's Page Counter Object.)
Our solution, then, was simple - just rename the client's various HTML pages to ASP pages and
slap in the new ASP counter code. Oh, but wait! The final gotcha
with this problem (and the reason for this article) is that the client
pages had to maintain the exact same file names (meaning we could not rename the files
from .htm to .asp)! Our customer did not want to have to tell
it's clients, who already had letterhead, business cards, signs, ... etc.
with their "Web-Address" on them, that their "Web-Address" was going to
change. We still felt we should be able to use ASP, and keep the HTML
pages. Read on to see how we accomplished this.

Some Other Possible Solutions

From the Web master, Scott Mitchell
There are a number of other workarounds that Greg and his team could have applied. For example,
they could have renamed all of the static pages from a .htm extension to a
.asp extension. Then they could have created a Custom 404 Error Page to automatically
redirect those visitors who visit SomePage.htm to SomePage.asp.
(To learn more about creating Custom 404 Error pages be sure to read: Creating
a Custom 404 Error Page.) Also, Greg and his team could have, through the IIS MMC, specified that
.htm pages be processed by asp.dll, thereby making HTML pages capable of running
ASP code. (An example of employing this technique can be seen here.)
Greg has informed me that these techniques were addressed when deciding what approach to take and, for
various reasons, were not acceptible...

So to provide a dynamic hit counter through a static HTML page, we needed to accomplish two tasks:

We needed a way to call an ASP page from a static HTML page.

We needed a way to get the dynamic counter value displayed back onto
the HTML page.

Why do we need to have the HTML page call an ASP page? If we could do this we
could let a waiting ASP page know we wanted a certain counter incremented.
We figured we could use an HTML image tag, setting the SRC property to the
path of our waiting ASP page, along with our counter ID like so:

<img src="/counters/hitcounter.asp?c_id=client1">

(This technique - using an ASP page in the src of an img
tag - is illustrated and discussed in further detail in:
Protecting Images)

This worked and solved the problem of calling an ASP page from inside a static
HTML page; however, in using the image tag we created another problem. We had
first figured by using the HTML image tag we could simply pass a counter's
value back as an image. We quickly found this was not going to be easily
accomplished. In researching a solution we did find a component that would
allow us to create a single GIF image of the counter's value on the fly. The
component was called gifactory.

Unfortunately, this
solution would not work for us because our customer's hosting company would
not allow us to register components on their shared servers. We decided to satisfy the HTML
pages image request we would pass back a custom gif called "counterlogo.gif".
But we still needed a way to get the dynamic counter value back to the HTML
page. While searching the web for another project we had going on, we found
an article on using JavaScript includes and a light bulb went ON! That was it!
If we could have our ASP page write the value of our counter into a JavaScript
include file we could get our counter displayed on our HTML page by simply
using a JavaScript include like so:

Our ASP page which is referenced through img tag actually creates the client-side
JavaScript file client1.js. Since the JavaScript include file is created when the browser
requests the image's src file (the ASP page), the browser may have already included the client-side
JavaScript file. This means that our counter's display will actually be off a bit, at times, usually only by one,
though.

That's it! Part 2 of this article contains the source for the ASP/HTML
page hit counter, HitCounter.asp. The code is well commented and should be
fairly easy to follow.

Advertiser Disclosure:
Some of the products that appear on this site are from companies from which QuinStreet receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. QuinStreet does not include all companies or all types of products available in the marketplace.