第三节:诸葛布阵、将士磨刀
xml数据存储结构以完成,下面一一列出完成论坛大业所需要的材料
项目包括{
通用函数页
(建立或一或二这种通用函数页或dll或者是用户控件,将常用的程序过程、变量、函数放入其中,此后使用可大大节省时间避免重复劳动,这在下一章将有所提及)
游客与会员的区分
(即是一个session,本例为session("who")值是否存在的判断,如存在即判断是会员,如不存在值即为游客,我们本例不使用cookies存储用户数据,游客权限自然是只能浏览帖子,不能发表或回复帖子,而会员则可以)
会员注册
(包含各种表单的页面,目的是完成向user.xml添加一新的标签节点(等同添加一新的会员数据),要处理好用户所提交的数据,方法要用到防止跨站提交、会员帐号(即xml节点头标签)要用正则表达式限制为类似程序变量的语法要求或干脆只允许使用英文字母、xml节点属性至少要过滤<>&"'以及回车符号、防止申请的会员帐号以存在user.xml、所有数据英文符号均转换为小写格式即不区分大小写包括用户帐号和密码)
会员登陆
(包含用户帐号输入框、密码输入框和一个登陆按钮,提交后利用xmldom搜索user.xml是否有匹配的用户帐号(要特别注意过滤用户提交的数据,尤其是*号等,这在xmldom的搜索中被认为是通配符),如user.xml存有该帐号,即将一个session,本例为session("who"),设值为该用户帐号,游客身份即成为会员身份)
会员资料修改
(禁止游客浏览本页,样式保持与会员注册页的表单基本一样(但不包含用户帐号名称修改的功能),只不过所有表单的值均是预读了user.xml中匹配session("who")该会员的信息,用户修改过后,单击完成修改按钮,此时后台程序修改user.xml中该会员对应的节点数据即可)
会员资料显示
(只读页面,读取网址参数中对应的会员帐号,显示会员所有无需保密的信息)
一个论坛栏目主页
(即帖子列表,根据url页码参数分页,显示data目录中对应页码的所有帖子信息,排序自然根据文件的修改日期,最新更新的最靠顶,这是开发本论坛中最难的一个项目之一,要谨慎处理,最好实现点对点(即1-10,30-40,100-110)形式分页的抽取data目录中的文件,可以保证最优质的运行速度)
帖子显示页
(本例的帖子显示是直接在浏览器访问xml文件,即http://xxx.xxx.xxx/xxx.xml的url形式访问,由于仅仅使用静态xsl控制xml文件的二层输出形式是远远不够的,所以我们采取的显示结构是三层,其顺序为(1:打开xml文件后查找xml-stylesheet节点的href所指定的xsl文件---2:由于目标文件类型是aspx,我们在目标aspx中根据url参数访问参考对应的xml文件数据,控制数据流输出格式为xsl,丛中很好的整理出理想的xsl样式表,即起到了中间层的关键作用---3:由于aspx输出的xsl是我们在后台整理过的,其高度的智能、合理,即可以配合xml数据输出结构复杂的帖子显示页),期间中间层的开发难度最大,是本论坛系统中最难的一个步骤,简单的地方是xmldom分析抽取目标xml中的节点数据,实现显示主题、显示帖子作者、显示帖子内容、显示帖子所有回复,但最难点,本人在着手开发时,就无法解决帖子回复的分页,以及aspx服务器端控件和xsl文档规范相互冲突,可能是本人水平有限,或也是本人原创的这种3层输出存在本质的缺陷,所谓xml实现数据库容易,但通过xsl实现超越html的理想输出难)
发表新贴
(禁止游客发表,该项目即是一个输入主题的输入框+内容输入框+提交按钮,可以绑定在栏目帖子列表页下方或新建一个专页,用户提交发表后要用server.htmlencode()过滤用户所提交的数据,而后用程序创建xml文件、给xml文件起名、整理xml文件的文件格式如第二节所写的格式、向节点内写入过滤后的数据、修改user.xml对应的发贴会员的节点实现积分+2和发贴数+1,用cookies限制7秒内禁止多次提交灌水)
回复新贴
(禁止游客回复,该页可绑定帖子显示页下方或新建一个专业,提供一内容输入框+提交按钮,提交后如发表新贴过程类同,要进行数据过滤,而后在对应的帖子存储xml文件中插入一reply节点,在该节点中建立用于存储回复作者名称、回复内容、回复日期、回复更新日期等节点,修改user.xml对应的发贴会员的节点实现积分+1和发贴数+1,用cookies限制7秒内禁止多次提交灌水)
版主管理功能
(要实现密码验证,判断禁止游客及会员使用,可选的后台管理功能有奖励会员积分、减少会员积分、删除会员、修改任何帖子、删除任何帖子,甚至可以考虑诸多封ip、置顶、锁定、封版主等等高级功能)
}
第四节:君临沙场、锦囊相助
通过以上三节修炼,君若仔细攻读,定已胸有成竹,跃跃欲试,此时想必已经动起手来,或者是思路很清晰却不知程序该如何写,若真是如此,不必急噪,笔者先将平生所学一些常用“兵法”一一列出,定可使汝茅塞顿开
1:错误提示函数(需要时使用,可弹出对话框给与用户错误提醒,而后自动退回上一页,此函数建议保存为一通用文件,需要时<!--#include file="publicfun.aspx"-->一下即可使用)
<script language=vb runat='server'>
sub t2(tstr2 as string)
response.write (replace("<script language=vbs> msgbox " & chr(34) & tstr2 & chr(34) & ",16," & chr(34) & "错误提示" & chr(34) & ":history.back()</script>","<","<")):response.end
end sub
</script>
2:一般数据检测函数(修改xml标签属性时建议使用,用于一般检测,至于用户帐号等还需要更严密的数据过滤)
<script language=vb runat='server'>
sub jiancha(requeststr as string) '本例过滤'"<>&*,如有疏漏请补之
dim array1(5) as string
array1(0)="'":array1(1)=chr(34):array1(2)="<":array1(3)=">":array1(4)="&":array1(5)="*"
dim tempi as integer
for tempi=0 to ubound(array1)
if instr(requeststr,array1(tempi))<>0 then response.write (replace("<script language=vbs> msgbox " & chr(34) & "参考数据 " & requeststr & " 不可以含有禁止符号 [" & array1(tempi) & "] ,自动返回请更正" & chr(34) & ",16," & chr(34) & "错误提示" & chr(34) & vbcrlf & "history.back()</script>","<","<")):response.end
next
end sub
</script>
3:asp.net拒绝跨站提交注入(可在会员注册、会员修改页等表单较多的页使用)
<%
if lcase(mid(request.servervariables("http_referer"),8,len(request.servervariables("server_name"))))<>lcase(request.servervariables("server_name")) then t2("拒绝跨站提交!")
%>
4:向目标xml文件添加新节点
<%@import namespace='system.xml'%>
<%
dim userdom1=new xmldocument,userdom2,userdom3
userdom1.load (server.mappath("user.xml")) '装载需要操作的xml文件
userdom2=userdom1.selectsinglenode("alluser") '操作游标指向alluser节点,句柄给userdom2变量
userdom3=userdom1.createelement("fyw") '新创建一名为fyw的节点,并将句柄给userdom3变量
userdom3.setattribute("name","风云舞") '为userdom3添加节点属性,新属性名为name,值为风云舞
userdom3.setattribute("pass","123")
userdom3.innertext="测试" '设置userdom3节点所包含的数据
userdom2.appendchild(userdom3) 'userdom2即alluser节点下添加userdom3所描述的fyw节点
userdom1.save (server.mappath("user.xml")) '将变动后的新xml数据保存到user.xml
%>
5:修改xml节点
<%@import namespace='system.xml'%>
<%
dim userdom1=new xmldocument,userdom2
userdom1.load (server.mappath("user.xml"))
userdom2=userdom1.selectsinglenode("alluser").getelementsbytagname("fyw") '操作游标指向alluser节点下的fyw节点
userdom2(0).setattribute("name","风云舞") '设定fyw节点数组的第一个,将其name属性值修改为风云舞
userdom2(0).innertext="测试" '设定fyw节点数组的第一个,将其所包含的数据改为测试
userdom1.save (server.mappath("user.xml")) '将变动后的新xml数据保存到user.xml
%>
6:查找判断xml节点是否存在
<%@import namespace='system.xml'%>
<%
dim userdom1=new xmldocument
userdom1.load (server.mappath("user.xml")) '装载需要操作的xml文件
'以下正是本人为什么要用“用户帐号”标识用户唯一身份的目的,查找方便呀:)
if userdom1.selectsinglenode("alluser").getelementsbytagname("fyw").count<>0 then t2("fyw节点以存在")
%>
7:批量添加xml节点(在编写回复帖子时,用第4例提到的方法一个一个填加节点很麻烦,这时可以考虑用此方法批量填加)
<%@import namespace='system.xml'%>
<%
dim filedom=new xmldocument,filedom2
filedom.load(server.mappath("data\" & request.querystring("dex"))) 'request.querystring("dex")=6.xml
filedom2=filedom.createelement("reply")
'以下这种方法很方便,而且对xml文件的结构排版也很好,合理的空格和回车可以表现良好的xml文档结构
filedom2.innerxml=vbcrlf & " <anthor>" & session("who") & "</anthor>" & vbcrlf & " <date>" & now & "</date>" & vbcrlf & " <gengxindate>" & now & "</gengxindate>" & vbcrlf & " <body>" & neirong.value & "</body>" & vbcrlf & " "
filedom.selectsinglenode("document/record").appendchild(filedom2)
filedom.save(server.mappath("data\" & request.querystring("dex"))) 'request.querystring("dex")=6.xml
%>
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器