在《【ASP】连接Access数据库的登陆系统》(点击打开链接)中介绍了数据库增删改查的应用,完成了一个登录系统,只是代码非常凌乱,非常不容易维护。下面用一种MVC分层结构的思想,去优化ASP登录系统的写作,就算让你用这种已经日落山河的脚本语言去写作也要写好一点。
首先如下图,基于Access数据库Database.mdb中的一张user_info表,如下图:
完成如下图一个包括登录、注册、修改密码的用户账号系统:
这个系统的目录结构如下图,页面比较多,不过各司其职,分工明确:
一、M层
1、数据库操作类db.asp在《【ASP】利用数据库操作类优化数据库表的增删改查》(点击打开链接)中已经介绍过了,不过这次对其部分代码进行修改。在这个用户系统写作过程,发现利用构造函数与析构函数来操作Access数据库很不稳定,容易出现关闭、打开连接的互斥出错。因此直接分成两个方法,在每次getbySQL与setbySQL都自行开自行关,避免数据库连接的处理问题。
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%> <% '禁止缓存' Response.CacheControl="no-cache" Response.Expires=-1 Response.Charset="UTF-8" '配合第一行设定网页编码' '数据库操作类' Class DB Private CONN '数据库连接' Private RS '数据库查询结果集' Private Sub Open_db_connect() '类的构造过程,进行数据库连接、初始化数据库查询结果集的操作' Set CONN=server.createobject("ADODB.connection") if CONN.state<>1 then '判断现在数据库是否正在连接,才打开一次数据库,避免过多的数据库连接' CONN.open "DBQ="&server.MapPath("/my_asp/Database.mdb")&";password=root;DRIVER={Microsoft Access Driver (*.mdb)}" end if Set RS=server.CreateObject("adodb.recordset") End Sub Public Function getbySQL(sql) '根据sql语句,对数据库有返回结果查询' Open_db_connect() RS.open sql,CONN,1,3 if not (RS.bof or RS.eof) then '如果查询结果非空,就将所有查询结果压到数组里面' MyArray=RS.GetRows getbySQL=MyArray '返回这个记载查询结果的数组给前台' end if Close_db_connect() End Function Public Sub setbySQL(sql) '根据sql语句,对数据库进行无返回结果的操作' Open_db_connect() CONN.execute sql Close_db_connect() End Sub Private Sub Close_db_connect() '类的析构函数,主要是关闭数据库连接' if CONN.state=1 then '判断现在数据库是否打开,是,才关闭' CONN.close set Con=nothing end if End Sub End Class %>
<!-- #include file="db.asp" --> <% Set db_control=New DB '初始化用户操作类' Function has_this_user(username) '是否存在该用户的判断' MyArray=db_control.getbySQL("select * from user_info where username='"&username&"'") has_this_user=isarray(MyArray) End Function Function get_password(username) '根据用户名取得密码' MyArray=db_control.getbySQL("select password from user_info where username='"&username&"'") get_password=MyArray(0,0) End Function Sub insert_user(username,password) '插入用户' db_control.setbySQL("insert into user_info(username,password) values('"&username&"','"&password&"')") End Sub Sub update_user(username,password) '修改用户密码' db_control.setbySQL("update user_info set password='"&password&"' where username='"&username&"'") End Sub %>
先写V层,一是V层简单,二是C层是连接M层与V层的桥梁,配合两者才好解释。
1、index.html,没什么好说的,就是3个表单,注意表单处理的两个问题《【HTML】表单form中一单回车就提交的text、一点击就提交的button》(点击打开链接),《【JavaScript】在前台验证表单,必须使用onsubmit="return xx()"的形式》(点击打开链接),在你写作的过程中,如果你发现的Onsubmit函数不管用,很可能你的OnSubmit函数中途出现语法错误。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>用户系统</title> </head> <body> <h1>登录</h1> <form action="login.asp" method="post"> 用户名:<input type="text" name="username"/><br /> 密码:<input type="password" name="password"/><br /> <input type="submit" value="提交"/><br /> </form> <h1>注册</h1> <form action="register.asp" method="post" onsubmit="return register_check()"> 用户名:<input type="text" id="register_username" name="username"/><br /> 密码:<input type="password" id="register_password1" name="password"/><br /> 请再次输入密码:<input type="password" id="register_password2"/><br /> <input type="submit" value="提交"/><br /> </form> <h1>修改密码</h1> <form action="update.asp" method="post" onsubmit="return update_check()"> 用户名:<input type="text" id="update_username" name="username"/><br /> 旧密码:<input type="password" id="update_password" name="old_password"/><br /> 新密码:<input type="password" id="update_password1" name="new_password"/><br /> 请再次输入密码:<input type="password" id="update_password2"/><br /> <input type="submit" value="提交"/><br /> </form> </body> <script src="check_form.js"></script> </html>
function check_equal(password1,password2){//判断密码是否相等 if(password1==password2){ return true; } else{ return false; } } function register_check(){//注册表单的判断 var username=document.getElementById("register_username").value; var password1=document.getElementById("register_password1").value; var password2=document.getElementById("register_password2").value; if(username.length>0&&password1.length>0&&password2.length>0){ if(check_equal(password1,password2)){ return true; } else{ alert("两次输入的密码不一致!"); } } else{ alert("用户名、密码任意一项为空!"); } return false; } function update_check(){//修改密码表单的判断 var username=document.getElementById("update_username").value; var password=document.getElementById("update_password").value; var password1=document.getElementById("update_password1").value; var password2=document.getElementById("update_password2").value; if(username.length>0&&password.length>0&&password1.length>0&&password2.length>0){ if(check_equal(password1,password2)){ return true; } else{ alert("两次输入的密码不一致!"); } } else{ alert("用户名、密码任意一项为空!"); } return false; }
最后C层,其实C层的处理有了M层中user.asp的基础,获取V层中index.html表单传递过来的值,根据相关的判断,进行一番处理,打印一段弹出并跳转的JS和用户交互就行了。打印的JS脚本用asp中的&不停连接字符串地。根据判断进行构造。
这里还要注意一点,亲测,要对response.write打印出的javascript,先加上一个charset="utf-8",进行强行的编码控制,否则会在不明情况产生乱码,毕竟asp,也就是vbscript这门语言确实古老。
1、首先是登录处理login.asp的代码:
<!-- #include file="user.asp" --> <% username=Request.Form("username") password=Request.Form("password") info="<script charset='utf-8'>" if has_this_user(username) then if password=get_password(username) then info=info&"alert('登录成功!');" else info=info&"alert('密码错误!');" end if else info=info&"alert('查无此人!');" end if info=info&"window.location.href='index.html'" info=info&"</script>" response.Write info %>
<!-- #include file="user.asp" --> <% username=Request.Form("username") password=Request.Form("password") info="<script charset='utf-8'>" if has_this_user(username) then info=info&"alert('已有该用户,请换个用户名注册!');" else call insert_user(username,password) info=info&"alert('注册成功!');" end if info=info&"window.location.href='index.html'" info=info&"</script>" response.Write info %>
<!-- #include file="user.asp" --> <% username=Request.Form("username") old_password=Request.Form("old_password") new_password=Request.Form("new_password") info="<script charset='utf-8'>" if has_this_user(username) then if old_password=get_password(username) then call update_user(username,new_password) info=info&"alert('修改成功!');" else info=info&"alert('密码错误!');" end if else info=info&"alert('查无此人!');" end if info=info&"window.location.href='index.html'" info=info&"</script>" response.Write info %>
通过这样的ASP分层,可以让代码变得更加地清晰,同时,容易维护与修改。
不会让脚本语言等夹杂在一切,写完一次就毫无可读性,修改起来要找半天。