ASP 教程

什么是 ASP?

ASP(Active Server Pages)是微软推出的服务端脚本环境,用于动态生成网页内容。ASP 页面以 .asp 为扩展名,在服务器端执行脚本后再把 HTML 发送给浏览器。

ASP 的核心特点

  • 服务端执行:脚本在服务器运行,浏览器只收到结果 HTML
  • 内置对象:Request、Response、Session、Application 等简化开发
  • 组件支持:可调用 COM 组件扩展功能
  • 数据库访问:通过 ADO 操作 Access、SQL Server 等数据库

脚本语言

ASP 默认使用 VBScript,也支持 JScript(JavaScript)。示例:

<%@ Language="VBScript" %>
<%
  Response.Write "Hello, World!"
%>

运行环境

  • Windows 服务器上的 IIS(Internet Information Services)
  • 需要启用 ASP 功能(控制面板 → 程序 → 启用或关闭 Windows 功能)

与 ASP.NET 的区别

项目ASPASP.NET
脚本语言VBScript/JScriptC#/VB.NET
编译方式解释执行编译执行
页面文件.asp.aspx
事件模型无Web Forms 事件模型

本教程将系统讲解 ASP 的语法、内置对象、表单处理、文件操作与数据库访问。

ASP 简介

ASP 简介

ASP 由微软于 1996 年推出,是早期 Web 动态开发的主流技术之一,在 2000 年代广泛用于中小型网站。

工作原理

  1. 浏览器请求 .asp 文件
  2. IIS 服务器读取文件并执行其中的脚本代码
  3. 脚本生成纯 HTML 结果
  4. 服务器把结果发送回浏览器显示

第一个 ASP 页面

<!DOCTYPE html>
<html>
<body>
<% Response.Write("欢迎来到 ASP 教程") %>
<p>当前时间:<%= Now() %></p>
</body>
</html>

保存为 first.asp 放到网站的虚拟目录中,通过浏览器访问即可看到动态输出。

ASP 能做什么

  • 动态显示数据库内容
  • 处理用户表单提交
  • 用户登录与权限控制(Session)
  • 文件上传与下载
  • 发送电子邮件
  • 计数器、留言板、内容管理系统等

代码块语法

<% 这是服务端代码块 %>
<%= 表达式输出 %>

注意事项

  • ASP 代码区分大小写不严格,但建议统一风格
  • 代码块内不能直接写 HTML,需用 Response.Write 输出
  • 中文页面建议文件编码保存为 UTF-8 并设置 Response.Charset

ASP 安装

ASP 安装与运行环境配置

运行 ASP 需要 Windows + IIS 环境。下面是 IIS 中启用 ASP 的完整步骤。

1. 启用 IIS

  1. 打开"控制面板" → "程序" → "启用或关闭 Windows 功能"
  2. 勾选 "Internet Information Services"(IIS)
  3. 展开 IIS → 万维网服务 → 应用程序开发功能,勾选 "ASP"
  4. 点击确定,等待安装完成

2. 创建网站目录

C:\inetpub\wwwroot\mysite

把 .asp 文件放入该目录,如 hello.asp。

3. 浏览测试

浏览器访问 http://localhost/mysite/hello.asp,看到页面输出即配置成功。

4. 配置默认文档

  1. IIS 管理器 → 选中站点 → 双击"默认文档"
  2. 添加 index.asp、default.asp 等名称

5. 父路径设置(常见报错)

使用 ../ 引用父目录时报错时:

  1. IIS 管理器 → 站点 → ASP → 打开"行为"设置
  2. 把"启用父路径"设为 True

6. 常见问题排查

  • 页面显示源码:ASP 未启用,回到步骤 1 勾选
  • 500 错误:脚本语法错误,查看详细错误信息
  • 权限不足:检查目录的 IIS_IUSRS 读取权限

ASP 语法

ASP 语法基础

ASP 页面由 HTML 与服务端脚本混合组成,脚本用 <% ... %> 包围。

脚本块

<%
  Dim name
  name = "张三"
  Response.Write "你好, " & name
%>

表达式输出

<p>你的 IP 是:<%= Request.ServerVariables("REMOTE_ADDR") %></p>

注释

<%
  ' 这是单行注释(VBScript)
  ' 注释内容不会被执行
  Response.Write "Hello"
%>
<!-- 这是 HTML 注释,会发送到浏览器 -->

变量声明

<%
  Dim a, b, c   ' 声明多个变量
  a = 10
  b = 20
  c = a + b     ' c = 30
%>

条件语句

<%
  Dim score
  score = 85
  If score >= 90 Then
    Response.Write "优秀"
  ElseIf score >= 60 Then
    Response.Write "及格"
  Else
    Response.Write "不及格"
  End If
%>

循环语句

<%
  Dim i
  For i = 1 To 5
    Response.Write "第 " & i & " 次循环<br>"
  Next

  Do While i > 0
    i = i - 1
  Loop
%>

过程与函数

<%
  Sub SayHello(name)
    Response.Write "你好," & name
  End Sub

  Function Add(x, y)
    Add = x + y
  End Function

  Call SayHello("张三")
  Response.Write Add(3, 4)
%>

ASP 变量

ASP 变量

变量用于在脚本运行期间保存数据,VBScript 中的变量不需要声明类型,但建议用 Dim 显式声明。

变量声明

<%
  Dim strName    ' 字符串
  Dim intAge     ' 数字
  Dim arr        ' 数组
  Dim obj        ' 对象
%>

强制声明(推荐)

<%@ Language="VBScript" %>
<%
  Option Explicit   ' 强制所有变量必须先声明,避免拼写错误
  Dim x
  x = 10
%>

数据类型(Variant)

<%
  Dim v
  v = "Hello"          ' 字符串
  v = 100              ' 数字
  v = 3.14             ' 浮点
  v = True             ' 布尔
  v = #2026-08-01#     ' 日期(用 # 包围)
  v = Null             ' 空值
%>

类型转换函数

<%
  Dim s, n
  s = "123"
  n = CInt(s)          ' 转整数
  n = CDbl(s)          ' 转浮点
  n = CLng(s)          ' 转长整型
  s = CStr(456)        ' 转字符串
  Response.Write CInt("100") + 1   ' 输出 101
%>

作用域

<%
  Dim globalVar        ' 页面级变量,整个页面有效
  Sub Test()
    Dim localVar       ' 过程内变量,仅过程内有效
    localVar = 1
  End Sub
%>

会话与应用变量

<%
  Session("username") = "张三"      ' 会话级,每个用户独立
  Application("visits") = Application("visits") + 1  ' 应用级,所有用户共享
%>

变量命名规范

  • 以字母开头,不能包含空格或特殊字符
  • 不区分大小写,但建议保持统一
  • 避免与内置关键字冲突

ASP 程序

ASP 程序结构与控制流程

ASP 页面按从上到下的顺序执行脚本,支持完整的控制流程语句。

If...Then...Else

<%
  Dim hour
  hour = Hour(Now())
  If hour < 12 Then
    Response.Write "上午好"
  ElseIf hour < 18 Then
    Response.Write "下午好"
  Else
    Response.Write "晚上好"
  End If
%>

Select Case

<%
  Dim weekday
  weekday = Weekday(Now())
  Select Case weekday
    Case 1: Response.Write "星期日"
    Case 2, 3, 4, 5, 6: Response.Write "工作日"
    Case 7: Response.Write "星期六"
    Case Else: Response.Write "未知"
  End Select
%>

For...Next

<%
  Dim i, sum
  sum = 0
  For i = 1 To 100
    sum = sum + i
  Next
  Response.Write "1+2+...+100 = " & sum
%>

For Each...Next(遍历集合)

<%
  Dim item
  For Each item In Request.Form
    Response.Write item & " = " & Request.Form(item) & "<br>"
  Next
%>

Do...Loop

<%
  Dim n
  n = 0
  Do While n < 5
    Response.Write n & " "
    n = n + 1
  Loop
  Response.Write "<br>"
  Do
    Response.Write "至少执行一次"
  Loop While False
%>

Sub 与 Function

<%
  Sub ShowMsg(msg)
    Response.Write "<div class='msg'>" & msg & "</div>"
  End Sub

  Function Factorial(n)
    If n <= 1 Then
      Factorial = 1
    Else
      Factorial = n * Factorial(n - 1)
    End If
  End Function

  Call ShowMsg("5! = " & Factorial(5))
%>

ASP 表单

ASP 处理表单

ASP 通过 Request.Form(POST)和 Request.QueryString(GET)接收表单数据。

GET 方式

<!-- 提交到 get.asp -->
<form method="get" action="get.asp">
  姓名: <input type="text" name="name">
  <input type="submit" value="提交">
</form>
<!-- get.asp 接收 -->
<%
  Dim name
  name = Request.QueryString("name")
  Response.Write "你好, " & name
%>
<!-- URL 形如 get.asp?name=张三 -->

POST 方式

<form method="post" action="post.asp">
  用户名: <input type="text" name="username"><br>
  密码: <input type="password" name="pwd"><br>
  <input type="submit" value="登录">
</form>
<!-- post.asp -->
<%
  Dim u, p
  u = Request.Form("username")
  p = Request.Form("pwd")
  If u = "admin" And p = "123456" Then
    Response.Write "登录成功,欢迎 " & u
  Else
    Response.Write "用户名或密码错误"
  End If
%>

复选框与多选

<input type="checkbox" name="hobby" value="篮球">篮球
<input type="checkbox" name="hobby" value="足球">足球
<input type="checkbox" name="hobby" value="游泳">游泳
<%
  Dim hobby
  ' 多个同名值用逗号分隔
  hobby = Request.Form("hobby")
  Response.Write "你的爱好: " & hobby
  ' 或逐个遍历
  Dim i
  For i = 1 To Request.Form("hobby").Count
    Response.Write Request.Form("hobby")(i) & "<br>"
  Next
%>

表单验证

<%
  Dim email
  email = Trim(Request.Form("email"))
  If email = "" Then
    Response.Write "邮箱不能为空"
  ElseIf InStr(email, "@") = 0 Then
    Response.Write "邮箱格式不正确"
  Else
    Response.Write "邮箱有效: " & email
  End If
%>

ASP Cookies

ASP Cookies

Cookie 是服务器写入浏览器的小段文本,用于在多次请求之间保存用户状态,如记住登录、购物车、偏好设置。

写入 Cookie

<%
  Response.Cookies("username") = "张三"
  Response.Cookies("username").Expires = Date() + 30   ' 30 天后过期
  ' 不设置 Expires 则为会话级 Cookie,关闭浏览器失效
%>

读取 Cookie

<%
  Dim user
  user = Request.Cookies("username")
  If user <> "" Then
    Response.Write "欢迎回来, " & user
  Else
    Response.Write "你是新访客"
  End If
%>

设置多个值(集合 Cookie)

<%
  Response.Cookies("user")("name") = "李四"
  Response.Cookies("user")("age") = "28"
  Response.Cookies("user").Expires = Date() + 7
%>
<%
  Response.Write Request.Cookies("user")("name")
  Response.Write Request.Cookies("user")("age")
%>

删除 Cookie

<%
  ' 把过期时间设为过去时间即可删除
  Response.Cookies("username") = ""
  Response.Cookies("username").Expires = Date() - 1
%>

判断 Cookie 是否存在

<%
  If Len(Request.Cookies("token")) > 0 Then
    Response.Write "已有登录凭证"
  Else
    Response.Write "未登录"
  End If
%>

Cookie 属性

<%
  Response.Cookies("theme").Domain = "example.com"   ' 域名
  Response.Cookies("theme").Path = "/"               ' 路径
  Response.Cookies("theme").Secure = True            ' 仅 HTTPS 传输
  Response.Cookies("theme").Expires = Date() + 365   ' 有效期
%>

注意事项

  • Cookie 必须在任何 HTML 输出之前写入
  • 单个 Cookie 大小限制约 4KB
  • 敏感数据不要直接存 Cookie,建议加密或存 Session

ASP Session

ASP Session(会话)

Session 在服务器端保存每个用户的独立数据,配合 Cookie 中的 SessionID 识别用户,用于登录状态、购物车等。

设置 Session

<%
  Session("username") = "admin"
  Session("role") = "管理员"
  Session.Timeout = 30   ' 空闲 30 分钟自动过期
%>

读取 Session

<%
  If Session("username") <> "" Then
    Response.Write "当前用户: " & Session("username")
  Else
    Response.Write "未登录"
  End If
%>

登录示例

<%
  Dim u, p
  u = Request.Form("username")
  p = Request.Form("pwd")
  If u = "admin" And p = "123456" Then
    Session("login") = True
    Session("username") = u
    Response.Redirect "index.asp"
  Else
    Response.Write "登录失败"
  End If
%>

登录校验页面(首页保护)

<%
  If Session("login") <> True Then
    Response.Redirect "login.asp"
    Response.End
  End If
%>
<!DOCTYPE html>
<html><body>
<h1>欢迎 <%= Session("username") %> 访问会员区</h1>
</body></html>

销毁 Session(退出登录)

<%
  Session.Abandon   ' 结束会话
  Response.Redirect "login.asp"
%>

Session 常用属性与方法

<%
  Session.SessionID      ' 会话唯一 ID
  Session.Timeout        ' 超时分钟数(默认 20)
  Session.CodePage       ' 字符编码页,如 65001(UTF-8)
  Session.Contents.Remove("username")   ' 移除单个键
  Session.Contents.RemoveAll()          ' 清空所有键
%>

Session 与 Cookie 对比

特性SessionCookie
存储位置服务器浏览器
安全性较高较低(可被篡改)
大小限制较大约 4KB
生命周期超时或 Abandon按 Expires

ASP Application

ASP Application 对象

Application 对象用于在所有用户之间共享数据,适合统计在线人数、全局配置、计数器等场景。

设置与读取

<%
  Application("siteName") = "老王编程学习站"
  Application("visits") = 1000
  Response.Write Application("siteName")
%>

网站访问计数器

<%
  Application.Lock                 ' 锁定,防止并发冲突
  Application("visits") = Application("visits") + 1
  Application.UnLock               ' 解锁
  Response.Write "你是第 " & Application("visits") & " 位访客"
%>

在线人数统计(结合 Session 事件)

<!-- Global.asa 中定义 -->
<script language="VBScript" runat="server">
Sub Application_OnStart
  Application("online") = 0
End Sub
Sub Session_OnStart
  Application.Lock
  Application("online") = Application("online") + 1
  Application.UnLock
End Sub
Sub Session_OnEnd
  Application.Lock
  Application("online") = Application("online") - 1
  Application.UnLock
End Sub
</script>
<!-- 页面显示 -->
<p>当前在线人数: <%= Application("online") %></p>

数组存 Application

<%
  Dim users(2)
  users(0) = "张三"
  users(1) = "李四"
  Application.Lock
  Application("userList") = users
  Application.UnLock

  Dim arr
  arr = Application("userList")
  Response.Write arr(0)
%>

注意事项

  • 修改 Application 数据前必须 Lock,改完 UnLock
  • Application 数据存在内存中,服务器重启会清空
  • 不要存放大量数据,会影响性能
  • 不要用 Application 存储用户私有数据(该用 Session)

ASP #include

ASP #include 指令

#include 指令用于在页面中嵌入其他文件的内容,实现代码复用,如公共头部、页脚、数据库连接文件。

语法

<!-- #include virtual="/includes/header.asp" -->
<!-- #include file="footer.asp" -->
  • file:相对路径,基于当前文件所在目录
  • virtual:虚拟路径,基于网站根目录

公共页头示例

<!-- header.asp -->
<div class="site-header">
  <h1>老王编程学习站</h1>
  <nav><a href="index.asp">首页</a> | <a href="about.asp">关于</a></nav>
</div>
<!-- 各页面引用 -->
<!-- #include file="header.asp" -->
<p>页面主体内容...</p>
<!-- #include file="footer.asp" -->

数据库连接复用

<!-- dbconn.asp -->
<%
  Dim conn
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("data.mdb")
%>
<!-- 使用 -->
<!-- #include file="dbconn.asp" -->
<%
  Dim rs
  Set rs = Server.CreateObject("ADODB.Recordset")
  rs.Open "SELECT * FROM news", conn
  ' ... 使用后关闭
  rs.Close: Set rs = Nothing
  conn.Close: Set conn = Nothing
%>

包含带逻辑的文件

<!-- check_login.asp -->
<%
  If Session("login") <> True Then
    Response.Redirect "login.asp"
  End If
%>
<!-- 受保护页面 -->
<!-- #include file="check_login.asp" -->

嵌套包含

<!-- a.asp 中包含 b.asp,b.asp 中又包含 c.asp,逐层展开 -->
<!-- 注意:避免循环包含导致死循环 -->

ASP Global.asa

ASP Global.asa

Global.asa 是 ASP 应用的全局文件,必须放在网站根目录,用于定义应用级事件与全局变量。

文件结构

<script language="VBScript" runat="server">
Sub Application_OnStart
  ' 应用第一次被请求时执行(仅一次)
End Sub
Sub Application_OnEnd
  ' 应用结束时执行
End Sub
Sub Session_OnStart
  ' 每个新会话开始时执行
End Sub
Sub Session_OnEnd
  ' 会话结束时执行
End Sub
</script>

初始化全局配置

<script language="VBScript" runat="server">
Sub Application_OnStart
  Application("siteName") = "老王编程学习站"
  Application("pageSize") = 10
  Application("online") = 0
End Sub
</script>

欢迎新用户

<script language="VBScript" runat="server">
Sub Session_OnStart
  Application.Lock
  Application("online") = Application("online") + 1
  Application.UnLock
  Session("startTime") = Now()
End Sub
Sub Session_OnEnd
  Application.Lock
  If Application("online") > 0 Then
    Application("online") = Application("online") - 1
  End If
  Application.UnLock
End Sub
</script>

声明对象(可省略,建议代码中创建)

<object runat="server" scope="Application" id="MyConn" progid="ADODB.Connection"></object>
<object runat="server" scope="Session" id="MyRs" progid="ADODB.Recordset"></object>

注意事项

  • Global.asa 不能包含 <% %> 代码块,只能用 <script> 标签
  • 修改 Global.asa 后,服务器会重启应用使修改生效
  • 必须放在站点根目录才能生效
  • Session_OnEnd 在会话超时或调用 Abandon 后触发

ASP 发送电子邮件

ASP 发送电子邮件

ASP 常用 CDO.Message(Collaboration Data Objects)组件发送邮件,也可使用第三方 SMTP 组件。

使用 CDO 发送邮件

<%
  Dim objMail
  Set objMail = Server.CreateObject("CDO.Message")

  ' SMTP 服务器配置
  With objMail.Configuration.Fields
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.example.com"
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
    .Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
    .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "sender@example.com"
    .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
    .Update
  End With

  objMail.From = "sender@example.com"          ' 发件人
  objMail.To = "receiver@example.com"          ' 收件人
  objMail.Subject = "邮件主题"                  ' 主题
  objMail.TextBody = "这是邮件正文内容。"        ' 正文

  objMail.Send
  Set objMail = Nothing
  Response.Write "邮件发送成功"
%>

发送 HTML 邮件

<%
  objMail.HTMLBody = "<h1>欢迎注册</h1><p>点击<a href='http://example.com/verify'>这里</a>激活账号</p>"
  objMail.Send
%>

添加附件

<%
  objMail.AddAttachment Server.MapPath("files/report.pdf")
  objMail.Send
%>

群发邮件

<%
  Dim toList
  toList = "a@example.com;b@example.com;c@example.com"
  objMail.To = Replace(toList, ";", ",")
  objMail.Send
%>

表单联系页面示例

<%
  Dim name, email, msg
  name = Request.Form("name")
  email = Request.Form("email")
  msg = Request.Form("message")

  If name = "" Or email = "" Or msg = "" Then
    Response.Write "请填写完整"
  Else
    Dim objMail
    Set objMail = Server.CreateObject("CDO.Message")
    objMail.From = email
    objMail.To = "admin@example.com"
    objMail.Subject = "网站联系表单: " & name
    objMail.TextBody = "来自: " & name & vbCrLf & "邮箱: " & email & vbCrLf & "内容: " & msg
    objMail.Send
    Set objMail = Nothing
    Response.Write "留言已发送,我们会尽快回复!"
  End If
%>

常见问题

  • 服务器未安装 CDO 组件时会报 "服务器创建对象失败"
  • SMTP 认证失败:检查用户名密码与端口(SSL 通常用 465/587)
  • 发送到本域可能被 SMTP 服务器拦截,需配置白名单

ASP Response

ASP Response 对象

Response 对象用于向浏览器发送输出内容,是 ASP 中最常用的对象之一。

输出文本

<%
  Response.Write "Hello World"
  Response.Write "<br>第二行"
  Response.Write("括号写法也可以")
%>

Redirect 重定向

<%
  Response.Redirect "http://www.example.com"   ' 跳到外部
  Response.Redirect "login.asp"                ' 跳到站内页面
%>
<!-- 注意:Redirect 前不能有输出内容,否则报错 -->

End 停止执行

<%
  Response.Write "前半段"
  Response.End          ' 立即停止,后面的代码不再执行
  Response.Write "这行不会输出"
%>

Buffer 缓冲

<%
  Response.Buffer = True    ' 开启缓冲(通常在第一行设置)
  Response.Write "先缓存"
  Response.Clear            ' 清空缓冲区
  Response.Write "重新输出"
  Response.Flush            ' 立即发送缓冲区内容
  Response.Write "后续内容"
%>

设置字符编码

<%
  Response.Charset = "UTF-8"         ' 字符集
  Response.ContentType = "text/html"
  ' 输出 JSON
  Response.ContentType = "application/json"
  Response.Write "{""name"":""张三""}"
%>

控制缓存与过期

<%
  Response.Expires = 30             ' 浏览器缓存 30 分钟
  Response.ExpiresAbsolute = #2026-12-31 23:59:59#
  Response.CacheControl = "private" ' 或 "no-cache"
  Response.AddHeader "Refresh", "5;url=index.asp"   ' 5 秒后跳转
%>

状态码设置

<%
  Response.Status = "404 Not Found"
  Response.Write "页面不存在"
  ' 常见: 200 OK / 301 Moved Permanently / 403 Forbidden / 500 Internal Server Error
%>

输出二进制(下载文件)

<%
  Response.ContentType = "application/octet-stream"
  Response.AddHeader "Content-Disposition", "attachment;filename=file.zip"
  ' 配合 ADODB.Stream 输出文件内容
%>

ASP Request

ASP Request 对象

Request 对象用于获取客户端发送的各种信息:URL 参数、表单数据、Cookie、服务器变量等。

QueryString(URL 参数)

<!-- 访问 product.asp?id=5 -->
<%
  Dim id
  id = Request.QueryString("id")
  If id = "" Then
    Response.Write "缺少参数"
  Else
    Response.Write "商品 ID: " & id
  End If
%>

Form(POST 表单)

<%
  Dim username
  username = Request.Form("username")
  Response.Write "提交的用户名: " & username
%>

Cookies

<%
  Dim token
  token = Request.Cookies("token")
  Response.Write "Cookie 值: " & token
%>

ServerVariables(服务器变量)

<%
  Response.Write "客户端 IP: " & Request.ServerVariables("REMOTE_ADDR") & "<br>"
  Response.Write "请求方法: " & Request.ServerVariables("REQUEST_METHOD") & "<br>"
  Response.Write "请求 URL: " & Request.ServerVariables("URL") & "<br>"
  Response.Write "浏览器: " & Request.ServerVariables("HTTP_USER_AGENT") & "<br>"
  Response.Write "服务器端口: " & Request.ServerVariables("SERVER_PORT") & "<br>"
  Response.Write "脚本名: " & Request.ServerVariables("SCRIPT_NAME")
%>

获取客户端 IP 的完整方式

<%
  Dim ip
  ip = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
  If ip = "" Then
    ip = Request.ServerVariables("REMOTE_ADDR")
  End If
  ' 取第一个 IP(代理时可能多个,逗号分隔)
  If InStr(ip, ",") > 0 Then
    ip = Trim(Left(ip, InStr(ip, ",") - 1))
  End If
  Response.Write "真实 IP: " & ip
%>

泛集合访问

<%
  Dim key
  For Each key In Request.QueryString
    Response.Write key & " = " & Request.QueryString(key) & "<br>"
  Next
%>

获取二进制(上传文件)

<%
  Dim binData
  binData = Request.BinaryRead(Request.TotalBytes)
  ' 需要配合 ADODB.Stream 解析 multipart 数据
%>

安全提示

  • 所有用户输入都要过滤,防 SQL 注入与 XSS
  • 用 Server.HTMLEncode 转义输出到页面的数据
  • 长度限制:QueryString 默认最多 2048 字符

ASP Server

ASP Server 对象

Server 对象提供服务器相关的功能:创建组件、路径转换、编码、脚本超时控制等。

创建组件对象

<%
  Set conn = Server.CreateObject("ADODB.Connection")
  Set rs = Server.CreateObject("ADODB.Recordset")
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
%>

MapPath(虚拟路径转物理路径)

<%
  Response.Write Server.MapPath("/")                ' 网站根目录
  Response.Write "<br>" & Server.MapPath("data.mdb")  ' 当前目录下的文件
  Response.Write "<br>" & Server.MapPath("/upload/files")
%>

HTMLEncode(HTML 转义)

<%
  Dim input
  input = "<script>alert('xss')</script>"
  Response.Write Server.HTMLEncode(input)
  ' 输出 &lt;script&gt;...,浏览器显示为文本,防止 XSS
%>

URLEncode / URLDecode

<%
  Dim url
  url = "http://example.com/search?q=" & Server.URLEncode("ASP 教程")
  Response.Write url
  ' URLDecode 还原编码
  Response.Write Server.URLDecode("%E6%95%99%E7%A8%8B")
%>

脚本超时控制

<%
  Server.ScriptTimeout = 60    ' 脚本最多执行 60 秒,防止死循环拖垮服务器
  Response.Write "脚本超时设置为 " & Server.ScriptTimeout & " 秒"
%>

Execute 与 Transfer

<%
  ' Execute:执行另一个 ASP 文件,执行完后继续
  Server.Execute "helper.asp"

  ' Transfer:跳转到另一个页面(URL 不变,比 Redirect 高效)
  Server.Transfer "error.asp"
%>

GetLastError(获取错误对象)

<%
  Dim err
  Set err = Server.GetLastError()
  If Not err Is Nothing Then
    Response.Write "错误描述: " & err.Description
  End If
%>

常见用途

  • 创建 COM 组件实现功能扩展
  • 路径转换配合文件操作
  • 输出转义提升安全性

ASP Error

ASP 错误处理

健壮的 ASP 程序需要处理运行时错误,防止页面白屏或泄露敏感信息。

On Error 语句

<%
  On Error Resume Next   ' 出错后继续执行(不中断)
  Dim result
  result = 1 / 0         ' 除零错误
  If Err.Number <> 0 Then
    Response.Write "发生错误: " & Err.Description
    Err.Clear            ' 清除错误状态
  End If
  On Error GoTo 0        ' 恢复默认错误处理
%>

错误对象属性

<%
  On Error Resume Next
  Call RiskyOperation()
  If Err.Number <> 0 Then
    Response.Write "错误号: " & Err.Number & "<br>"
    Response.Write "描述: " & Err.Description & "<br>"
    Response.Write "来源: " & Err.Source
    Err.Clear
  End If
%>

数据库操作错误处理

<%
  On Error Resume Next
  Dim conn
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "错误连接字符串"
  If Err.Number <> 0 Then
    Response.Write "数据库连接失败: " & Err.Description
    Err.Clear
  Else
    Response.Write "连接成功"
    conn.Close: Set conn = Nothing
  End If
%>

自定义错误页

<!-- error.asp:友好错误提示页 -->
<%
  Dim msg
  msg = Request.QueryString("msg")
  If msg = "" Then msg = "未知错误"
%>
<!DOCTYPE html>
<html><body>
  <h1>出错了</h1>
  <p><%= Server.HTMLEncode(msg) %></p>
  <a href="index.asp">返回首页</a>
</body></html>
<!-- 使用时 -->
<%
  On Error Resume Next
  ' ... 业务代码 ...
  If Err.Number <> 0 Then
    Response.Redirect "error.asp?msg=" & Server.URLEncode(Err.Description)
  End If
%>

IIS 自定义错误页配置

  1. IIS 管理器 → 站点 → 错误页
  2. 双击"500"错误 → 编辑 → 选择"在此网站上执行 URL"
  3. 填 /error.asp 并保存

错误日志

<%
  On Error Resume Next
  Dim fso, logFile
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set logFile = fso.OpenTextFile(Server.MapPath("error.log"), 8, True)
  logFile.WriteLine Now() & " - " & Err.Description
  logFile.Close
%>

最佳实践

  • 生产环境不向用户显示详细错误信息
  • 重要操作(写库、发邮件)必须加错误处理
  • 记录错误日志便于排查

ASP FileSystem

ASP FileSystemObject 文件系统

FileSystemObject(FSO)是 ASP 操作文件系统的核心组件,可读写文件、管理文件夹、获取磁盘信息。

创建 FSO 对象

<%
  Dim fso
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
%>

文件夹操作

<%
  Dim fso, folder
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Dim path
  path = Server.MapPath("/upload")

  ' 判断文件夹是否存在
  If fso.FolderExists(path) Then
    Response.Write "文件夹存在"
  Else
    fso.CreateFolder(path)   ' 创建文件夹
    Response.Write "已创建"
  End If

  ' 删除文件夹(注意:会递归删除内容)
  ' fso.DeleteFolder path

  ' 移动/重命名
  ' fso.MoveFolder path, Server.MapPath("/backup")
%>

遍历文件夹

<%
  Dim fso, folder, subFolder, file
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set folder = fso.GetFolder(Server.MapPath("/upload"))

  For Each subFolder In folder.SubFolders
    Response.Write "子文件夹: " & subFolder.Name & "<br>"
  Next
  For Each file In folder.Files
    Response.Write "文件: " & file.Name & " (" & file.Size & " 字节)<br>"
  Next
%>

文件判断与操作

<%
  Dim fso, path
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  path = Server.MapPath("config.ini")

  If fso.FileExists(path) Then
    Response.Write "文件存在,大小: " & fso.GetFile(path).Size
    ' fso.DeleteFile path          ' 删除
    ' fso.CopyFile path, dest      ' 复制
    ' fso.MoveFile path, dest      ' 移动
  End If
%>

获取文件属性

<%
  Dim fso, file
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set file = fso.GetFile(Server.MapPath("data.txt"))

  Response.Write "名称: " & file.Name & "<br>"
  Response.Write "大小: " & file.Size & " 字节<br>"
  Response.Write "创建时间: " & file.DateCreated & "<br>"
  Response.Write "修改时间: " & file.DateLastModified & "<br>"
  Response.Write "类型: " & file.Type & "<br>"
  Response.Write "路径: " & file.Path
%>

驱动器信息

<%
  Dim fso, drive
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  For Each drive In fso.Drives
    If drive.IsReady Then
      Response.Write "盘符: " & drive.DriveLetter & " 总容量: " & FormatNumber(drive.TotalSize/1024/1024/1024, 2) & " GB, 剩余: " & FormatNumber(drive.FreeSpace/1024/1024/1024, 2) & " GB<br>"
    End If
  Next
%>

安全提示

  • 文件路径拼接时要校验用户输入,防止目录穿越攻击
  • 删除操作不可恢复,务必先确认
  • 对写入目录设置合适的权限

ASP TextStream

ASP TextStream 文本文件读写

TextStream 对象由 FSO 创建,用于逐行或整体读写文本文件。

创建并写入文件

<%
  Dim fso, ts
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  ' 第二个参数: 2=覆盖写入, 8=追加写入
  ' 第三个参数: True=创建(不存在时)
  Set ts = fso.CreateTextFile(Server.MapPath("log.txt"), True, True)
  ts.WriteLine "第一行内容"
  ts.WriteLine "第二行内容"
  ts.Close
  Set ts = Nothing
  Response.Write "写入完成"
%>

追加内容

<%
  Dim fso, ts
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set ts = fso.OpenTextFile(Server.MapPath("log.txt"), 8, True)
  ts.WriteLine Now() & " - 用户访问了页面"
  ts.Close
  Set ts = Nothing
%>

读取整个文件

<%
  Dim fso, ts, content
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set ts = fso.OpenTextFile(Server.MapPath("data.txt"), 1)  ' 1=只读
  content = ts.ReadAll
  ts.Close
  Response.Write "文件内容:<pre>" & Server.HTMLEncode(content) & "</pre>"
%>

逐行读取

<%
  Dim fso, ts, line
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set ts = fso.OpenTextFile(Server.MapPath("log.txt"), 1)
  Do While Not ts.AtEndOfStream
    line = ts.ReadLine
    Response.Write Server.HTMLEncode(line) & "<br>"
  Loop
  ts.Close
%>

读取指定行数

<%
  Dim fso, ts, i
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set ts = fso.OpenTextFile(Server.MapPath("log.txt"), 1)
  For i = 1 To 10
    If ts.AtEndOfStream Then Exit For
    Response.Write ts.ReadLine & "<br>"
  Next
  ts.Close
%>

计数器文件示例

<%
  Dim fso, ts, count
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Dim path
  path = Server.MapPath("counter.txt")

  If fso.FileExists(path) Then
    Set ts = fso.OpenTextFile(path, 1)
    count = CLng(ts.ReadLine)
    ts.Close
  Else
    count = 0
  End If

  count = count + 1
  Set ts = fso.CreateTextFile(path, True)
  ts.WriteLine count
  ts.Close
  Response.Write "你是第 " & count & " 位访客"
%>

注意编码问题

<%
  ' 中文写入 UTF-8 时建议使用 ADODB.Stream
  Dim stream
  Set stream = Server.CreateObject("ADODB.Stream")
  stream.Type = 2            ' 文本模式
  stream.Charset = "UTF-8"
  stream.Open
  stream.WriteText "中文内容", 1
  stream.SaveToFile Server.MapPath("utf8.txt"), 2
  stream.Close
%>

ASP Drive

ASP Drive 驱动器对象

Drive 对象用于获取磁盘驱动器信息,如盘符、类型、容量与剩余空间。

获取指定驱动器

<%
  Dim fso, drive
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set drive = fso.GetDrive("C:")
  If drive.IsReady Then
    Response.Write "盘符: " & drive.DriveLetter & "<br>"
    Response.Write "总容量: " & FormatNumber(drive.TotalSize / 1024 / 1024 / 1024, 2) & " GB<br>"
    Response.Write "剩余空间: " & FormatNumber(drive.FreeSpace / 1024 / 1024 / 1024, 2) & " GB<br>"
    Response.Write "已用空间: " & FormatNumber((drive.TotalSize - drive.FreeSpace) / 1024 / 1024 / 1024, 2) & " GB<br>"
    Response.Write "序列号: " & drive.SerialNumber & "<br>"
    Response.Write "卷标: " & drive.VolumeName & "<br>"
  Else
    Response.Write "驱动器未就绪(如光驱无盘)"
  End If
%>

遍历所有驱动器

<%
  Dim fso, drive
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  For Each drive In fso.Drives
    Response.Write "盘符 " & drive.DriveLetter & ": "
    If drive.IsReady Then
      Response.Write "可用, 剩余 " & FormatNumber(drive.FreeSpace/1024/1024/1024, 2) & " GB"
    Else
      Response.Write "未就绪"
    End If
    Response.Write "<br>"
  Next
%>

驱动器类型

<%
  Dim fso, drive
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set drive = fso.GetDrive("C:")
  Select Case drive.DriveType
    Case 0: Response.Write "未知类型"
    Case 1: Response.Write "可移动磁盘"
    Case 2: Response.Write "固定硬盘"
    Case 3: Response.Write "网络磁盘"
    Case 4: Response.Write "CD-ROM"
    Case 5: Response.Write "RAM 磁盘"
  End Select
%>

磁盘健康监控示例

<%
  Dim fso, drive, warn
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  For Each drive In fso.Drives
    If drive.IsReady Then
      Dim freePct
      freePct = drive.FreeSpace / drive.TotalSize * 100
      If freePct < 10 Then
        Response.Write "警告: " & drive.DriveLetter & " 盘剩余空间不足 10%!<br>"
        warn = True
      End If
    End If
  Next
  If Not warn Then Response.Write "所有磁盘空间充足"
%>

ASP File

ASP File 文件对象

File 对象表示文件系统中的单个文件,提供属性访问与复制、移动、删除等操作。

获取文件对象

<%
  Dim fso, file
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set file = fso.GetFile(Server.MapPath("report.pdf"))
%>

文件属性

<%
  Response.Write "文件名: " & file.Name & "<br>"
  Response.Write "不含扩展名: " & fso.GetBaseName(file.Path) & "<br>"
  Response.Write "扩展名: " & fso.GetExtensionName(file.Path) & "<br>"
  Response.Write "大小: " & file.Size & " 字节<br>"
  Response.Write "创建: " & file.DateCreated & "<br>"
  Response.Write "修改: " & file.DateLastModified & "<br>"
  Response.Write "最后访问: " & file.DateLastAccessed & "<br>"
  Response.Write "完整路径: " & file.Path & "<br>"
  Response.Write "父文件夹: " & file.ParentFolder
%>

复制与移动

<%
  Dim fso
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Dim src, dst
  src = Server.MapPath("data.txt")
  dst = Server.MapPath("backup/data_copy.txt")

  fso.CopyFile src, dst, True      ' True=覆盖已存在
  fso.MoveFile src, Server.MapPath("archive/data.txt")
%>

删除文件

<%
  Dim fso
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Dim path
  path = Server.MapPath("temp.txt")
  If fso.FileExists(path) Then
    fso.DeleteFile path
    Response.Write "已删除"
  End If
%>

列出目录下的文件(带条件过滤)

<%
  Dim fso, folder, file
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set folder = fso.GetFolder(Server.MapPath("/upload"))

  For Each file In folder.Files
    If LCase(fso.GetExtensionName(file.Path)) = "jpg" Or LCase(fso.GetExtensionName(file.Path)) = "png" Then
      Response.Write "<img src='/upload/" & file.Name & "' width='80'> " & file.Name & " (" & file.Size & "B)<br>"
    End If
  Next
%>

文件类型判断

<%
  Dim fso, file
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set file = fso.GetFile(Server.MapPath("photo.jpg"))
  Select Case LCase(fso.GetExtensionName(file.Path))
    Case "jpg", "png", "gif": Response.Write "图片文件"
    Case "pdf": Response.Write "PDF 文档"
    Case "zip", "rar": Response.Write "压缩包"
    Case Else: Response.Write "其他类型"
  End Select
%>

ASP Folder

ASP Folder 文件夹对象

Folder 对象表示文件系统中的文件夹,用于遍历子项、管理文件夹结构。

获取 Folder 对象

<%
  Dim fso, folder
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set folder = fso.GetFolder(Server.MapPath("/upload"))
%>

文件夹属性

<%
  Response.Write "名称: " & folder.Name & "<br>"
  Response.Write "路径: " & folder.Path & "<br>"
  Response.Write "创建时间: " & folder.DateCreated & "<br>"
  Response.Write "修改时间: " & folder.DateLastModified & "<br>"
  Response.Write "父文件夹: " & folder.ParentFolder & "<br>"
  Response.Write "子文件夹数: " & folder.SubFolders.Count & "<br>"
  Response.Write "文件数: " & folder.Files.Count & "<br>"
  Response.Write "总大小: " & FormatNumber(folder.Size/1024, 2) & " KB"
%>

遍历子文件夹与文件

<%
  Dim fso, folder, sub, file
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set folder = fso.GetFolder(Server.MapPath("/upload"))

  Response.Write "=== 子文件夹 ===<br>"
  For Each sub In folder.SubFolders
    Response.Write "📁 " & sub.Name & "<br>"
  Next

  Response.Write "=== 文件 ===<br>"
  For Each file In folder.Files
    Response.Write "📄 " & file.Name & " (" & file.Size & "B)<br>"
  Next
%>

创建与删除文件夹

<%
  Dim fso, base
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  base = Server.MapPath("/data")

  ' 创建多级文件夹(不存在则逐级创建)
  If Not fso.FolderExists(base & "\2026") Then
    fso.CreateFolder base & "\2026"
  End If
  If Not fso.FolderExists(base & "\2026\08") Then
    fso.CreateFolder base & "\2026\08"
  End If

  ' 删除空文件夹
  ' fso.DeleteFolder base & "\temp"
%>

按日期归档文件

<%
  Dim fso, folder, file, targetDir
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set folder = fso.GetFolder(Server.MapPath("/temp"))

  targetDir = Server.MapPath("/archive/") & Year(Date())
  If Not fso.FolderExists(targetDir) Then
    fso.CreateFolder targetDir
  End If

  For Each file In folder.Files
    If DateDiff("d", file.DateLastModified, Date()) > 30 Then
      fso.MoveFile file.Path, targetDir & "\" & file.Name
    End If
  Next
  Response.Write "归档完成"
%>

目录树递归遍历

<%
  Dim fso
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Call ShowTree(fso.GetFolder(Server.MapPath("/upload")), 0)

  Sub ShowTree(folder, level)
    Dim sub, file, i
    For i = 1 To level: Response.Write "--": Next
    Response.Write folder.Name & "/<br>"
    For Each file In folder.Files
      For i = 1 To level + 1: Response.Write "--": Next
      Response.Write file.Name & "<br>"
    Next
    For Each sub In folder.SubFolders
      Call ShowTree(sub, level + 1)
    Next
  End Sub
%>

ASP Dictionary

ASP Dictionary 字典对象

Scripting.Dictionary 是键值对集合,类似其他语言的字典/映射,适合快速查找与去重统计。

创建字典

<%
  Dim dict
  Set dict = Server.CreateObject("Scripting.Dictionary")
%>

添加与读取

<%
  Dim dict
  Set dict = Server.CreateObject("Scripting.Dictionary")

  dict.Add "name", "张三"
  dict.Add "age", 28
  dict.Add "city", "北京"

  Response.Write "姓名: " & dict("name") & "<br>"
  Response.Write "年龄: " & dict("age") & "<br>"
  ' 不存在的键返回空
  Response.Write "不存在的键: '" & dict("nonexist") & "'"
%>

判断键是否存在

<%
  If dict.Exists("name") Then
    Response.Write "键 name 存在"
  Else
    Response.Write "键不存在"
  End If
%>

修改与删除

<%
  dict("age") = 29          ' 修改值(键存在时)
  dict.Remove "city"        ' 删除键值对
  ' dict.RemoveAll           ' 清空全部
  Response.Write "键值对数量: " & dict.Count
%>

遍历字典

<%
  Dim key
  For Each key In dict.Keys
    Response.Write key & " = " & dict(key) & "<br>"
  Next
  ' 或按值遍历
  Dim v
  For Each v In dict.Items
    Response.Write v & "<br>"
  Next
%>

单词统计示例

<%
  Dim dict, text, word, arr
  Set dict = Server.CreateObject("Scripting.Dictionary")
  text = "apple banana apple orange banana apple"
  arr = Split(text, " ")

  For Each word In arr
    If dict.Exists(word) Then
      dict(word) = dict(word) + 1
    Else
      dict.Add word, 1
    End If
  Next

  For Each word In dict.Keys
    Response.Write word & ": " & dict(word) & " 次<br>"
  Next
%>

配置参数示例

<%
  Dim config
  Set config = Server.CreateObject("Scripting.Dictionary")
  config.Add "dbName", "knowledge_site"
  config.Add "pageSize", 10
  config.Add "debug", True

  ' 读取配置
  Dim db
  db = config("dbName")
  Response.Write "数据库: " & db
%>

注意事项

  • 添加已存在的键会报错,先判断 Exists
  • 键是区分大小写的吗?Dictionary 默认不区分大小写
  • 适合少量配置数据;大量数据建议用数据库

ASP ADO

ASP ADO 数据库访问

ADO(ActiveX Data Objects)是 ASP 访问数据库的标准接口,支持 Access、SQL Server、MySQL 等。

连接 Access 数据库

<%
  Dim conn
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("data.mdb")
%>

连接 SQL Server

<%
  Dim conn
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=mydb;User ID=sa;Password=123456"
%>

连接 MySQL(需要驱动)

<%
  Dim conn
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "Driver={MySQL ODBC 8.0 Unicode Driver};Server=localhost;Database=mydb;User=root;Password=123456;Option=3"
%>

查询记录集

<%
  Dim conn, rs
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("data.mdb")

  Set rs = Server.CreateObject("ADODB.Recordset")
  rs.Open "SELECT * FROM news ORDER BY id DESC", conn

  Do While Not rs.EOF
    Response.Write rs("title") & "<br>"
    rs.MoveNext
  Loop

  rs.Close: Set rs = Nothing
  conn.Close: Set conn = Nothing
%>

执行增删改

<%
  Dim conn
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "连接字符串"

  ' 插入
  conn.Execute "INSERT INTO news (title, content) VALUES ('测试标题', '测试内容')"
  ' 更新
  conn.Execute "UPDATE news SET content='新内容' WHERE id=1"
  ' 删除
  conn.Execute "DELETE FROM news WHERE id=5"

  conn.Close: Set conn = Nothing
  Response.Write "操作成功"
%>

防 SQL 注入

<%
  Function SafeStr(s)
    If IsNull(s) Or s = "" Then
      SafeStr = ""
    Else
      SafeStr = Replace(Replace(s, "'", "''"), """, "\")
    End If
  End Function

  Dim uid
  uid = SafeStr(Request.Form("uid"))
  Dim rs
  Set rs = Server.CreateObject("ADODB.Recordset")
  rs.Open "SELECT * FROM users WHERE uid='" & uid & "'", conn
%>

分页查询

<%
  Dim rs, page, pageSize
  page = CLng(Request.QueryString("page"))
  If page < 1 Then page = 1
  pageSize = 10

  Set rs = Server.CreateObject("ADODB.Recordset")
  rs.PageSize = pageSize
  rs.CursorLocation = 3
  rs.Open "SELECT * FROM news ORDER BY id DESC", conn

  rs.AbsolutePage = page
  Dim i
  For i = 1 To pageSize
    If rs.EOF Then Exit For
    Response.Write rs("title") & "<br>"
    rs.MoveNext
  Next
  Response.Write "共 " & rs.PageCount & " 页"
%>

ASP AdRotator

ASP AdRotator 广告轮播组件

AdRotator 组件用于随机显示广告横幅,通过计划文件配置多个广告与权重。

创建计划文件

<!-- adrot.txt 广告计划文件 -->
REDIRECT adredir.asp
WIDTH 468
HEIGHT 60
BORDER 1
*
banner1.gif
http://www.example1.com
示例网站一
30
banner2.gif
http://www.example2.com
示例网站二
40
banner3.gif
http://www.example3.com
示例网站三
30

使用 AdRotator

<%
  Dim ad
  Set ad = Server.CreateObject("MSWC.AdRotator")
  ad.Border = 1
  ad.Clickable = True
  ad.TargetFrame = "_blank"
  Response.Write ad.GetAdvertisement("adrot.txt")
%>

重定向页面

<!-- adredir.asp:记录点击并跳转 -->
<%
  Dim url
  url = Request.QueryString("url")
  If url <> "" Then
    ' 可在此记录点击次数
    ' 数据库或文件计数
    Response.Redirect url
  Else
    Response.Redirect "index.asp"
  End If
%>

计划文件字段说明

字段说明
REDIRECT点击广告后跳转的 ASP 文件
WIDTH/HEIGHT广告图片尺寸
BORDER边框粗细
*分隔符
图片路径广告图片的相对路径
链接地址广告目标 URL
说明文字鼠标悬停提示(ALT)
权重显示概率,数值越大出现越多

随机显示原理

AdRotator 根据权重随机选择广告,权重和越高,该广告被选中的概率越大。上述示例中 banner2 权重 40,出现概率约 40%。

ASP BrowserCap

ASP BrowserCap 浏览器能力组件

BrowserCap 组件通过 User-Agent 判断浏览器的类型与能力,以便输出兼容的页面内容。

使用 BrowserCap

<%
  Dim bc
  Set bc = Server.CreateObject("MSWC.BrowserType")
  Response.Write "浏览器: " & bc.Browser & "<br>"
  Response.Write "版本: " & bc.Version & "<br>"
  Response.Write "平台: " & bc.Platform & "<br>"
%>

能力检测

<%
  Dim bc
  Set bc = Server.CreateObject("MSWC.BrowserType")
  If bc.Frames Then Response.Write "支持框架(Frames)<br>"
  If bc.Tables Then Response.Write "支持表格(Tables)<br>"
  If bc.JavaScript Then Response.Write "支持 JavaScript<br>"
  If bc.VBScript Then Response.Write "支持 VBScript<br>"
  If bc.Cookies Then Response.Write "支持 Cookie<br>"
  If bc.ActiveXControls Then Response.Write "支持 ActiveX 控件<br>"
  If bc.JavaApplets Then Response.Write "支持 Java Applets<br>"
%>

根据浏览器输出不同内容

<%
  Dim bc
  Set bc = Server.CreateObject("MSWC.BrowserType")
  If InStr(bc.Browser, "IE") > 0 Then
    Response.Write "<!-- 针对老 IE 的特殊处理 -->"
  ElseIf bc.Browser = "Chrome" Then
    Response.Write "现代浏览器,启用高级特性"
  Else
    Response.Write "通用内容"
  End If
%>

移动端判断

<%
  Dim bc, isMobile
  Set bc = Server.CreateObject("MSWC.BrowserType")
  isMobile = (InStr(LCase(Request.ServerVariables("HTTP_USER_AGENT")), "mobile") > 0) _
          Or (InStr(LCase(Request.ServerVariables("HTTP_USER_AGENT")), "android") > 0)
  If isMobile Then
    Response.Redirect "m/index.asp"
  End If
%>

配置说明

  • BrowserCap 依赖 browscap.ini 文件,位于 Windows 目录
  • 老浏览器识别可能不准,现代开发更多用 User-Agent 检测或特征检测
  • 该组件在现代项目中已较少使用,了解即可

ASP Content Linking

ASP Content Linking 内容链接组件

Content Linking 组件用于管理一组按顺序排列的页面,自动生成上一页/下一页导航,适合教程、文档类网站。

创建内容列表文件

<!-- links.txt 内容列表 -->
intro.asp  第一章 简介
chapter1.asp  第二章 基础知识
chapter2.asp  第三章 进阶内容
conclusion.asp  第四章 总结

使用 Content Linking

<%
  Dim cl
  Set cl = Server.CreateObject("MSWC.NextLink")
  Dim file
  file = "links.txt"

  ' 获取当前页 URL
  Dim cur
  cur = Request.ServerVariables("SCRIPT_NAME")
  cur = Mid(cur, InStrRev(cur, "/") + 1)

  Response.Write "当前第 " & cl.GetListIndex(file) & " 章 / 共 " & cl.GetListCount(file) & " 章<br>"
  Response.Write "当前标题: " & cl.GetListIndex(file) & "<br>"
%>

导航输出

<%
  Dim cl, file
  Set cl = Server.CreateObject("MSWC.NextLink")
  file = "links.txt"

  ' 上一章
  If cl.GetListIndex(file) > 1 Then
    Response.Write "<a href='" & cl.GetPreviousURL(file) & "'>← " & cl.GetPreviousDescription(file) & "</a>"
  Else
    Response.Write "← 已是第一章"
  End If
  Response.Write " | "
  ' 下一章
  If cl.GetListIndex(file) < cl.GetListCount(file) Then
    Response.Write "<a href='" & cl.GetNextURL(file) & "'>" & cl.GetNextDescription(file) & " →</a>"
  Else
    Response.Write "已是最后一章 →"
  End If
%>

目录输出

<%
  Dim cl, file, i
  Set cl = Server.CreateObject("MSWC.NextLink")
  file = "links.txt"
  Response.Write "<ul>"
  For i = 1 To cl.GetListCount(file)
    Response.Write "<li><a href='" & cl.GetNthURL(file, i) & "'>" & cl.GetNthDescription(file, i) & "</a></li>"
  Next
  Response.Write "</ul>"
%>

说明

  • 列表文件每行:URL + 空格 + 描述
  • URL 可以是相对路径或完整 URL
  • 适合小规模静态教程;大规模内容建议用数据库

ASP Content Rotator

ASP Content Rotator 内容轮转组件

Content Rotator 组件从内容计划文件中随机显示一段内容,常用于展示随机广告、随机名言、每日提示等。

创建内容计划文件

<!-- content.txt -->
%% // 权重 5 的内容
恭喜你获得了新用户优惠券!
%% // 权重 3
每日一签:努力终有回报。
%% // 权重 2
夏日促销正在进行中,全场 8 折!

%% 后注释表示该条内容的显示权重(数值越大越常出现)。

使用 Content Rotator

<%
  Dim cr
  Set cr = Server.CreateObject("MSWC.ContentRotator")
  Response.Write cr.ChooseContent("content.txt")
%>

循环显示全部内容

<%
  Dim cr, i, total
  Set cr = Server.CreateObject("MSWC.ContentRotator")
  total = cr.GetAllContent("content.txt")
  Response.Write total
%>

随机名言示例

<!-- quotes.txt -->
%% // 10
天才就是百分之一的灵感加上百分之九十九的汗水。—— 爱迪生
%% // 10
学而不思则罔,思而不学则殆。—— 孔子
%% // 10
千里之行,始于足下。—— 老子
<div class="quote-box">
  <%= Server.HTMLEncode(cr.ChooseContent("quotes.txt")) %>
</div>

与其他组件的区别

  • Content Rotator:同一页面内随机轮转文本内容
  • AdRotator:随机显示广告横幅图片
  • Content Linking:按顺序链接的一组页面导航

注意事项

  • 内容文件用 UTF-8 保存时注意编码
  • 选择结果每次请求随机,可用 Session 缓存避免刷新频繁变化

AJAX 简介

AJAX 简介

AJAX(Asynchronous JavaScript And XML)是一种无需刷新整个页面即可与服务器交换数据并更新部分页面的技术。

核心原理

  1. 浏览器通过 JavaScript 的 XMLHttpRequest(或 fetch)发起异步请求
  2. 服务器处理请求并返回数据(通常是 JSON 或 XML)
  3. JavaScript 解析响应并局部更新 DOM

原生 XMLHttpRequest 示例

<script>
function loadData() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "getdata.asp", true);
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) {
      document.getElementById("result").innerHTML = xhr.responseText;
    }
  };
  xhr.send();
}
</script>
<button>加载数据</button>
<div id="result"></div>

使用 fetch(现代方式)

<script>
fetch("getdata.asp")
  .then(function (resp) { return resp.text(); })
  .then(function (data) {
    document.getElementById("result").innerHTML = data;
  });
</script>

AJAX 的优势

  • 用户体验好:无需整页刷新
  • 减少数据传输量:只传需要的数据
  • 提高响应速度

与 ASP 结合

ASP 页面可以专门输出 AJAX 接口数据:

<!-- getdata.asp -->
<%
  Response.ContentType = "application/json"
  Response.Charset = "UTF-8"
  Dim name, age
  name = "张三"
  age = 28
  Response.Write "{""name"":""" & name & """,""age"":" & age & "}"
%>
<script>
fetch("getdata.asp")
  .then(function (r) { return r.json(); })
  .then(function (obj) {
    alert(obj.name + " " + obj.age);
  });
</script>

AJAX ASP

AJAX 与 ASP 结合实例

本节演示 AJAX 调用 ASP 接口的完整流程:前端发请求、ASP 处理、返回 JSON。

1. 用户名实时校验

<!-- checkuser.asp:返回 JSON -->
<%
  Response.ContentType = "application/json"
  Response.Charset = "UTF-8"
  Dim user
  user = Trim(Request.QueryString("user"))
  If user = "" Then
    Response.Write "{""ok"":false,""msg"":""用户名为空""}"
    Response.End
  End If
  ' 假设数据库判断
  Dim exists
  exists = False
  If user = "admin" Then exists = True
  If exists Then
    Response.Write "{""ok"":false,""msg"":""用户名已被占用""}"
  Else
    Response.Write "{""ok"":true,""msg"":""用户名可用""}"
  End If
%>
<input type="text" id="username">
<span id="userMsg"></span>
<script>
function checkUser() {
  var u = document.getElementById("username").value;
  fetch("checkuser.asp?user=" + encodeURIComponent(u))
    .then(function (r) { return r.json(); })
    .then(function (data) {
      var span = document.getElementById("userMsg");
      span.innerHTML = data.msg;
      span.style.color = data.ok ? "green" : "red";
    });
}
</script>

2. POST 提交表单(不刷新)

<!-- save.asp -->
<%
  Response.ContentType = "application/json"
  Response.Charset = "UTF-8"
  Dim title, content
  title = Request.Form("title")
  content = Request.Form("content")
  If title = "" Then
    Response.Write "{""ok"":false,""msg"":""标题必填""}"
  Else
    ' 假设已写入数据库
    Response.Write "{""ok"":true,""msg"":""保存成功"",""id"":123}"
  End If
%>
<script>
function saveData() {
  var fd = new FormData();
  fd.append("title", document.getElementById("t").value);
  fd.append("content", document.getElementById("c").value);
  fetch("save.asp", { method: "POST", body: fd })
    .then(function (r) { return r.json(); })
    .then(function (data) { alert(data.msg); });
}
</script>

3. 自动补全搜索

<!-- search.asp -->
<%
  Response.ContentType = "application/json"
  Response.Charset = "UTF-8"
  Dim kw
  kw = Request.QueryString("kw")
  ' 假设数据库查询返回数组
  Dim results
  results = Array("ASP 教程", "ASP 变量", "ASP Session", "ASP ADO")
  Response.Write "["
  Dim i, matched, first
  matched = False
  first = True
  For i = 0 To UBound(results)
    If InStr(results(i), kw) > 0 Then
      If Not first Then Response.Write ","
      Response.Write """数据: " & results(i) & """"
      first = False
      matched = True
    End If
  Next
  Response.Write "]"
%>

AJAX 数据库

AJAX 结合数据库操作

AJAX + ADO 的组合让页面可以动态加载数据库数据,实现无刷新的增删改查。

1. 动态加载列表

<!-- newslist.asp -->
<%
  Response.ContentType = "text/html"
  Response.Charset = "UTF-8"
  Dim conn, rs
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("data.mdb")
  Set rs = conn.Execute("SELECT TOP 5 id, title, addtime FROM news ORDER BY id DESC")

  Do While Not rs.EOF
    Response.Write "<div class='news-item'>"
    Response.Write "<h4>" & rs("title") & "</h4>"
    Response.Write "<small>" & rs("addtime") & "</small>"
    Response.Write "</div>"
    rs.MoveNext
  Loop
  rs.Close: Set rs = Nothing
  conn.Close: Set conn = Nothing
%>
<div id="newsBox">加载中...</div>
<script>
fetch("newslist.asp")
  .then(function (r) { return r.text(); })
  .then(function (html) { document.getElementById("newsBox").innerHTML = html; });
</script>

2. 返回 JSON 由前端渲染

<!-- apinews.asp -->
<%
  Response.ContentType = "application/json"
  Response.Charset = "UTF-8"
  Dim conn, rs, arr, i, json
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "连接字符串"
  Set rs = conn.Execute("SELECT id, title FROM news LIMIT 10")

  Dim items()
  i = 0
  ReDim items(rs.RecordCount - 1)
  Do While Not rs.EOF
    items(i) = "{""id"":" & rs("id") & ",""title"":""" & Replace(rs("title"), """", """") & """}"
    i = i + 1
    rs.MoveNext
  Loop
  Response.Write "[" & Join(items, ",") & "]"
  rs.Close: Set rs = Nothing
  conn.Close: Set conn = Nothing
%>

3. 分页加载

<!-- page.asp?page=1 -->
<%
  Dim page, pageSize
  page = CLng(Request.QueryString("page"))
  If page < 1 Then page = 1
  pageSize = 5
  Dim start
  start = (page - 1) * pageSize
  Dim conn, rs
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "连接字符串"
  Set rs = conn.Execute("SELECT id, title FROM news ORDER BY id DESC LIMIT " & start & ", " & pageSize)
  Do While Not rs.EOF
    Response.Write "<p>" & rs("title") & "</p>"
    rs.MoveNext
  Loop
%>
<button>加载第 2 页</button>
<script>
function loadPage(p) {
  fetch("page.asp?page=" + p)
    .then(function (r) { return r.text(); })
    .then(function (html) { document.getElementById("list").innerHTML = html; });
}
</script>

ASP 快速参考

ASP 快速参考

本节汇总 ASP 开发中常用的语法、对象、函数速查表。

内置对象速查

对象用途
Response输出内容、重定向、设置响应头
Request获取表单、URL 参数、Cookie、服务器变量
Session用户级会话数据
Application应用级共享数据
Server创建对象、路径转换、编码、超时
Err错误信息

Response 常用成员

Response.Write "文本"
Response.Redirect "url"
Response.End
Response.Clear / Flush
Response.Charset = "UTF-8"
Response.ContentType = "text/html"
Response.Expires = 30
Response.Status = "404 Not Found"
Response.Cookies("name") = "值"

Request 常用成员

Request.QueryString("key")   ' GET
Request.Form("key")          ' POST
Request.Cookies("key")       ' Cookie
Request.ServerVariables("REMOTE_ADDR")
Request.TotalBytes

VBScript 常用函数

Len(s) / Trim(s) / Left(s,n) / Right(s,n) / Mid(s,start,n)
InStr(s, sub) / Replace(s, a, b) / UCase(s) / LCase(s)
CInt / CLng / CDbl / CStr / IsNumeric / IsNull / IsArray
Now() / Date() / Time() / Year(d) / Month(d) / Day(d) / Hour(d)
FormatNumber(n, 2) / FormatDateTime(d, 2)
Array(...) / UBound(a) / Split(s, sep) / Join(a, sep)
Rnd / Abs / Int / Sqr / Round(n, 2)

常用运算符

算术: + - * / \ (整除) Mod (取余) ^ (幂)
比较: = <> < > <= >=
逻辑: And Or Not Xor
字符串: & (连接)

常用组件

ADODB.Connection / Recordset / Stream   ' 数据库与流
Scripting.FileSystemObject / TextStream / Dictionary
MSWC.AdRotator / NextLink / ContentRotator / BrowserType
CDO.Message                               ' 邮件

字符编码建议

<%@ Language="VBScript" CodePage=65001 %>
<%
  Response.Charset = "UTF-8"
%>

ASP 总结

ASP 总结

本教程系统讲解了 ASP 的核心知识,下面做整体回顾与学习建议。

知识体系回顾

  • 基础:ASP 原理、安装配置、语法、变量、流程控制
  • 数据交互:表单处理、Cookie、Session、Application
  • 内置对象:Response、Request、Server 三大核心对象
  • 文件系统:FSO、TextStream、Drive、File、Folder
  • 数据库:ADO 连接与增删改查、分页
  • 组件:AdRotator、BrowserCap、Content Linking、Content Rotator
  • 进阶:错误处理、邮件发送、AJAX 结合、Global.asa

开发要点

  1. 所有用户输入必须过滤,防 SQL 注入与 XSS
  2. 敏感操作前先验证 Session 登录状态
  3. 数据库连接及时关闭,释放资源
  4. 开启 Option Explicit 强制变量声明
  5. 生产环境关闭详细错误显示

ASP 的现状与取舍

ASP 已是较老的技术,官方早已停止更新,新项目建议使用 ASP.NET、PHP 或 Node.js 等现代技术。但在以下场景 ASP 仍有用武之地:

  • 维护存量 ASP 老系统
  • 快速搭建内部小工具
  • 学习 Web 动态开发原理

进阶方向

  • 学习 ASP.NET(C#)与现代 .NET 生态
  • 学习 SQL 数据库优化与设计
  • 掌握现代前端框架(Vue/React)与后端 API 设计

希望本教程对你有所帮助,动手实践是掌握 ASP 最好的方式!

ASP 实例

ASP 综合实例

本节通过一个"留言板"综合实例,串起表单、Session、数据库、分页等知识点。

1. 数据库表结构

CREATE TABLE messages (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(50) NOT NULL,
  content TEXT NOT NULL,
  addtime DATETIME DEFAULT NOW()
);

2. 公共连接文件 db.asp

<%
  Dim conn
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open "Driver={MySQL ODBC 8.0 Unicode Driver};Server=localhost;Database=mydb;User=root;Password=123456;Option=3"
%>

3. 发表留言 add.asp

<!-- #include file="db.asp" -->
<%
  Dim user, msg
  user = Session("username")
  If user = "" Then
    Response.Write "请先登录"
    Response.End
  End If
  msg = Trim(Request.Form("content"))
  If msg = "" Then
    Response.Write "留言内容不能为空"
    Response.End
  End If
  ' 转义防注入
  msg = Replace(msg, "'", "''")
  conn.Execute "INSERT INTO messages (username, content) VALUES ('" & user & "', '" & msg & "')"
  Response.Redirect "index.asp"
%>

4. 留言列表 index.asp

<!-- #include file="db.asp" -->
<%
  Dim page, pageSize
  page = CLng(Request.QueryString("page"))
  If page < 1 Then page = 1
  pageSize = 10
  Dim start
  start = (page - 1) * pageSize

  Dim rs
  Set rs = Server.CreateObject("ADODB.Recordset")
  rs.Open "SELECT * FROM messages ORDER BY id DESC LIMIT " & start & ", " & pageSize, conn

  Do While Not rs.EOF
    Response.Write "<div class='msg'>"
    Response.Write "<b>" & Server.HTMLEncode(rs("username")) & "</b> 发表于 " & rs("addtime") & "<br>"
    Response.Write Server.HTMLEncode(rs("content"))
    Response.Write "</div><hr>"
    rs.MoveNext
  Loop
  rs.Close: Set rs = Nothing
%>

<!-- 发表留言表单 -->
<form method="post" action="add.asp">
  <textarea name="content" rows="3" cols="50"></textarea><br>
  <input type="submit" value="发表留言">
</form>

5. 登录 login.asp

<%
  Dim u, p
  u = Request.Form("username")
  p = Request.Form("pwd")
  If u = "admin" And p = "123456" Then
    Session("username") = u
    Response.Redirect "index.asp"
  Else
    Response.Write "登录失败,请重试"
  End If
%>

完整流程

  1. 用户登录(写 Session)
  2. 访问留言板查看列表(数据库查询 + 分页)
  3. 填写留言提交(表单 → 防注入 → 插入数据库)
  4. 跳回列表看到新留言
第 1 / 34 节