很多人第一次接触ASP,打开一个.asp文件,看到 `<% ... %>` 这种尖括号加百分号的东西,第一反应是“这什么鬼”。其实它就是VBScript嵌在HTML里。IIS收到请求,把`<% %>`里的代码跑一遍,生成纯HTML丢给浏览器。就这么简单。
我2003年搭过一个小论坛,用的就是经典ASP。服务器是Windows 2000 + IIS 5.0,数据库Access。那时候PHP还在4.x阶段,很多人觉得ASP上手快——因为它跟VB语法几乎一样,变量不用声明类型,写起来确实省事。
来看个最基础的例子。新建一个`test.asp`,内容如下:
<% Dim name name = "张三" Response.Write "你好," & name %> 浏览器访问这个文件,页面上显示“你好,张三”。`Dim`声明变量,`Response.Write`往页面输出内容。注意`&`是字符串连接符,不是加号。这一点跟JavaScript不同,新手经常搞混。
ASP内置了五个常用对象:Request、Response、Server、Session、Application。Request负责拿数据——表单提交的、URL参数、Cookie都靠它。Response管输出和跳转。Session存单个用户的会话状态,Application存整个应用共享的数据。Server对象用来创建COM组件实例、做HTML编码。
举个表单处理的例子。假设有个登录页`login.asp`:
<form action="check.asp" method="post"> 用户名:<input type="text" name="username" /> <input type="submit" value="登录" /> </form> `check.asp`里这样接收:
<% Dim uname uname = Request.Form("username") If uname = "" Then Response.Write "用户名不能为空" Response.End End If Session("user") = uname Response.Redirect "index.asp" %> `Request.Form`读POST数据,`Request.QueryString`读GET参数。`Response.End`直接终止后续代码执行。`Session("user")`把用户名存进会话,后面页面直接读这个值就知道谁登录了。注意`Response.Redirect`之后代码还会继续跑,所以通常要跟一个`Response.End`。
数据库操作是ASP最常干的事。用ADO连接Access:
<% Dim conn, rs, sql Set conn = Server.CreateObject("ADODB.Connection") conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("data.mdb") sql = "SELECT * FROM users WHERE id=1" Set rs = conn.Execute(sql) If Not rs.EOF Then Response.Write rs("username") End If rs.Close conn.Close Set rs = Nothing Set conn = Nothing %> 这里有几个坑。`Server.MapPath`把相对路径转成物理路径,必须用,否则Access找不到文件。`Set`用来赋值对象引用,普通变量不用。用完一定要`Close`再`Set ... = Nothing`,不然IIS进程里连接池很快耗尽,网站直接卡死。我当年就因为这个,服务器跑两天就得重启一次。
SQL注入是ASP项目的重灾区。上面那种拼接字符串的写法,如果id来自用户输入,攻击者传个`1; DROP TABLE users--`就完了。正确的做法是用参数化查询或者至少过滤单引号。不过经典ASP的参数化命令对象写起来很啰嗦,很多人偷懒不写,这也是后来大家转.NET的原因之一。
调试ASP比较痛苦。没有像样的断点调试器,主要靠`Response.Write`打印中间变量。IIS报错默认只给一个500页面,要去IIS管理器里关掉“显示友好HTTP错误信息”才能看到具体行号和错误描述。这个设置我找了整整一个下午。
经典ASP早已停止更新,微软最后支持到Windows Server 2003时代。但你现在去搜,仍有大量老系统在跑ASP——政府内网、学校教务、小型企业ERP。维护这些系统的人,往往得硬着头皮读十几年前的代码。所以了解它,不是为了新项目选型,而是为了能看懂那些还在喘气的老页面。