返回
软件世界1999年第1期

Web页面计数器的开发

徐州市科学技术委员会 韩传武

  摘要 介绍了使用通用网关接口CGI编写Web页面计数器的两种方法。

  关键字: Web页面 计数器 CGI 图象处理

  现在因特网(Internet)的发展速度非常快,其中以万维网(WWW) 的发展尤为突出,每天都有新的WWW站点及大量Web页面出现。为了统计页面的访问率,一般在页面上放置计数器,用它来显示访问次数。一个设计良好的页面计数器除了具有计数功能外,还可以起到美化、活跃页面的作用。开发页面计数器需要多方面的知识,它涉及到超文本标识语言(HTML)、通用网关界面(CGI)以及图象处理。 在因特网上有专门提供计数器服务的站点,为没有开发能力的站点以及个人主页提供服务,有些甚至是免费的。但是由于每次访问页面时就要到这些站点去取计数值,用起来很不方便。下面介绍如何自己开发页面计数器。

一、页面计数器的分类

  从计数器在页面上的表现形式看,可将计数器分成两类。一类为文本计数器,它是用数字0--9的字符显示计数值;另一种为图象计数器,它是用数字0--9的图象显示计数值。其实除了使用0--9外,还可以使用其他能够表示计数值的任何字符和图象,如“一”至“九”、“零”至“玖”以及麻将、算盘等等。

二、页面计数器的实现方法

  由于每次访问页面时计数值都要改变,所以计数器的生成必须以动态方式实现,通常采用CGI、JAVA等技术方案,这里介绍采用CGI的实现方法。 CGI 也就是通用网关接口,它是在客户机Web浏览器、Web服务器和CGI 应用程序之间传递信息的一组规范。CGI应用程序就是符合这种规范的程序, 原则上可以用任何语言编写。浏览器、服务器和CGI应用程序间的信息传递如下图所示。

┌──────┐
│CGI应用程序 │
└──────┘
  ↑ │
  │ ↓
 ┌───┐        ┌───┐
 │ Web  │──────→ │ WWW │
 │浏览器│←────── │服 务│
 └───┘        └───┘
  客户机          服务器

  Web浏览器通过URL向Web服务器发出执行CGI应用程序的请求,服务器利用环境变量将信息传递至CGI应用程序,然后启动应用程序。应用程序执行预定义的任务,对计数器程序来说就是取得计数值,并根据计数值进行文本或图象的处理。应用程序将处理后的数据按照特定的格式通过标准输出流(STDOUT)回传给服务器。服务器从STDOUT接收到数据后,再添加标准HTTP标题,然后再回传给客户。

  下面采用Perl编写页面计数器CGI程序,Web服务器软件为Microsoft IIS2.0,运行在Windows NT平台上。如果要将CGI程序移植到UNIX 平台需要稍加改动代码。按照IIS的预定义, 在Web服务器根目录下有一个虚拟子目录scripts, 所有的CGI程序应放在该目录或其子目录中。在scripts下建立counter子目录,专门存放页面计数器CGI程序和其他相关文件,该目录的实际路径为d:\scripts\counter。

三、文本计数器的实现

  文本计数器就是嵌入在页面中能反映计数值的文本字符串。由于文本字符串不是一个可以独立访问的资源,它不能像图象那样通过<IMG>标签来取得, 所以计数值文本字符串只能和超文本文件一起生成。这样为了在页面中显示一个计数值,整个超文本文件都需要动态产生。 text. pl 是文本计数器的 CGI 程序, 其中counter.txt是用于保存计数值的文本文件并且只有一行内容,开始时内容为"1",以后每次执行CGI程序时其数值自动加1。变量$WIDTH用于控制计数器宽度。程序将计数值转换成一定宽度的字符串,并在动态生成超文本文件时将它嵌入到适当位置。启动该程序,在浏览器上会看到如下内容:

  欢迎第XXXXX位访问者

四、图象计数器的实现

  图象计数器就是一幅嵌入在页面中能反映计数值的图象,这种嵌入是通过超文本文件中的<IMG>标签实现的。由于图象是一个可以独立访问的资源, 所以可以做到计数器图象的生成与其所在的页面完全分离。这样图象计数器的CGI 程序的主要任务就是根据计数值动态合成一幅图象,并将其转换成一定格式的图象文件传回浏览器,这一点与文本计数器不同。目前超文本文件支持GIF和JPEG 两种图象格式,为了讨论问题方便,图象计数器使用的是256 色顺序存储并使用通用调色板无任何补充区的GIF格式图象,以后所说的图象都是这种。

  (一)、GIF图象的文件结构

  256色顺序存储并使用通用调色板无任何补充区的GIF文件结构:

数据地址 数据字节长度 数据名称
0 6 图象标志、版本,如GIF87a
6 2 图象宽度,以象素为单位
8 2 图象高度,以象素为单位
10 1 全局标志
11 1 背景色索引值
12 1 用于计算图象点的长宽比
13 768 通用调色板
781 1 图象数据区标志,值为0x2C
782 4 图象左上角在屏幕上的坐标
786 2 图象宽度,以象素为单位
788 2 图象高度,以象素为单位
790 1 局部标志
791 1 每象素所需位数,对256色为8
792 XXXX 压缩图象数据
792+XXXX 1 图象数据结束标志,为0x00

  其中全局标志的Bit7=1,表示使用通用调色板数据,Bit0..2=7表示为256色图象。局部标志的Bit7=0,表示没有局部调色板,Bit6=0表示图象数据为顺序存储。

  (二)、图象数据的准备

  CGI程序要生成GIF文件,需要知道相应图象的基本信息,如图象的高和宽;调色板数据;未压缩过的原始图象数据。将原始图象数据按照LZW压缩算法进行压缩,并将压缩后的数据与其他信息按照GIF文件格式合并即构成GIF文件。注意,原始图象数据一定是未压缩过的,它是指按照从左到右,从上到下的顺序取每个象素的颜色值组成的数据系列。

  下面分步骤说明如何准备图象数据
  1.使用图象处理软件,如PhotoShop制作十幅表示0-9的GIF图象, 要求它们具有相同的尺寸和颜色,满足上述GIF文件格式。
  2.在十幅图象文件中任选出一个,取出前792个字节生成图象头部文件(head), 其中包含图象基本信息和调色板数据。
  3.按照GIF-LZW解压缩算法对十个图象文件进行解压缩, 生成十个原始图象数据文件,它们具有相同的文件长度。限于篇幅在这里不能给出解压缩程序,有兴趣的读者可以参阅有关资料,或者按以下地址下载解压缩程序。
  http://168.160.132.68/download/upgif256.exe

  4.将单个数字图象的宽度和高度信息、头部文件和十个原始图象数据文件按照以下格式合并成一个文件。

数据地址 数据字节长度 数据名称
0 1 单个数字图象高度,以象素为单位
1 1 单个数字图象宽度,以象素为单位
2 792 图象头部
794 XXXX 数字0-9图象的原始图象数据

  5.重复步骤1-4生成不同图案类型的计数器图象文件,分别取名1.img、2.img...,并将它们存放到d:\scripts\counter目录中。
  6.为每个需要计数器的页面设定名称,并在d:\scripts\counter目录中建立相应的保存计数值的文本文件,其内容与文本计数器的相同。例如名为main的页面需要计数器,则在d:\scripts\counter目录下建立名为main.txt的文件。

  (三)、GIF图象数据压缩方法简介

  GIF图象文件压缩图象数据采用了LZW压缩原理,但为了提高压缩效率对压缩方式又作了修改,所以又称为GIF-LZW压缩算法,其基本原理如下:
  建立三份表格,即字头表、字尾表和代码表。从欲压缩的原始数据流中每次取出两个数据值组成一对字符,如第一、二个数据值组成一对字符,第二、三个数据值组成一对字符,依次类推。字符对中的前一个字符存入字头表,后一个字符存入字尾表,并给予这对字符一个代码且将此代码存入代码表。以后在遇到相同字符对时就用它的代码取而代之,并将此代码和原始数据流中的下一个数据值组成一个新的字符对再进行处理。将字头表中的数据值按照分段的方式存入文件,即生成压缩数据文件。在原始LZW压缩算法中数据项的长度固定为12个Bits,而在GIF-LZW中数据项的长度是变化的。256色图象的起始数据项长度为9个Bits, 当压缩代码值超过 9 个Bits所能表示的范围时,则数据项长度改成10,依次类推,最高为12个Bits。当压缩代码值超过最大代码值4095时,就需要重新编码,清除三个表格的内容,将数据项长度恢复成9个Bits。

  (四)、图象计数器CGI程序的启动和工作原理

  图象计数器CGI程序为counter.pl,它需要两个参数,user和type。user 指明计数器所在页面的名称,type指明使用那种类型的计数器。假如名为main的页面需要类型为1的计数器,则在main页面的适当位置嵌入下行内容
  <IMG SRC="http://host/scripts/counter/counter.pl?user=main&type=1">
  host代表主机的域名,使用时应当用实际的域名替换,当浏览 main 页面时,Web服务器就会自动启动counter.pl。
  counter.pl被启动后将按照以下步骤工作:
  1.通过分析Web服务器传递的环境变量找到计数值文本文件main.txt 和计数器图象文件1.img。
  2.从main.txt读取计数值,将计数值加1再写回文件,以备下次使用。
  3.$WIDTH是控制计数器宽度的变量,根据它和计数值以左补0 的方式生成计数值字符串,如计数值为123,$WIDTH为5,则计数值字符串为"00123", 这样就确定了计数器每位使用的数字。
  4.从1.img读取前2个字节,以确定单个数字图象的宽和高,再根据$WIDTH计算出整个计数器图象的宽和高。
  5.从1.img再读取792个字节的图象头部数据,修改其中偏移地址为6、8、786和788四处的宽度和高度值,以生成计数器图象的头部数据。
  6.通过标准输出向Web服务器回传数据,首先说明数据的MIME类型, 再传送计数器图象的头部数据$head。

print "Content-type:image/gif\n\n";

print $head;

  7.根据计数器图象的宽和高,申请足以容纳整个计数器图象的原始数据的内存空间,并依据计数器的每位数字从1.img读取相应的原始图象数据到内存中。
  8.按照GIF-LZW压缩算法对原始图象数据进行压缩,将压缩后的数据回传给Web服务器。
  9.最后输出图象数据的结束标记,终止程序。

print "\x00";

print ";";

exit;

五、结束语

  上面只是给出页面计数器的两种实现方法,使用的图象也只有一种格式,有兴趣的读者可以修改程序以适用于不同格式的图象。访问以下网址可以看到上述文本和图象计数器的显示效果,还可以申请免费计数器。

http://168.160.132.68/scripts/counter/text.pl

http://168.160.132.68/counter/counter.htm


Text.pl

Name:

Text.pl

Type:

Perl Program (application/x-perl)

Encoding:

base64

Counter.pl

Name:

Counter.pl

Type:

Perl Program (application/x-perl)

Encoding:

base64