简介:这套ASP源码实现百汇网3D网上展厅系统v2.0,面向具备一定ASP基础、希望学习动态网站与三维展示结合的开发者,也适合用于课程设计、毕业设计或中小型虚拟展厅项目的前后台参考。资源共161个文件,压缩包仅4.93MB,整体结构清晰:35个asp文件承担前台页面与后台管理核心逻辑,56个png、26个gif、13个jpg提供展厅场景图片素材,14个js脚本完善交互效果,8个css样式表控制视觉布局,另有xml配置和swf动画等资源,目录按功能模块划分,便于快速定位。已有229人学习下载。资源内置管理员相关页面,涵盖栏目管理、图片编辑、数据备份与还原、Md5加密验证等常用后台功能,便于理解ASP+Access/SQL的常规操作流程;从后台关键页面看,系统还包含数据导入导出、图片上传编辑、日志管理等模块,完整覆盖展厅内容维护流程,同时3D展示部分可借鉴其前端构思与动画切换方式,适合二次开发、功能扩展及毕业设计参考。
1. 老ASP里的3D展厅:为什么v2.0还在线上跑
2025年还在接手ASP源码项目的场景,多半是两种情况:一是老企业站的运维迁移,二是课程设计里的“古董”课题。百汇网3d网上展厅系统v2.0属于后者,但它比单纯交作业的CRUD多了两个值得拆的东西:3D展厅的切片式展示逻辑,以及一组在Access + ASP时代非常典型的后台管理文件。看下文件列表就能闻到经典味:Upclass.asp管父级分类,Admin_Pic.asp管图片上传,Admin_Data.asp管数据库备份,NoSQL.Asp负责过滤,ManageLog.asp记操作日志。这套结构放在今天依然能跑,而且背后暴露的MD5老化和上传校验问题,在现在的Python、PHP项目里一样会犯。适合两类人读:要复现老系统应付课程设计的学生,以及要在旧站上做安全加固的运维。
2. 后台链路拆解:从Admin_Index到Upclass的分类管理逻辑
2.1 Admin_Index的分栏框架与权限跳转
打开Admin_Index.asp,典型的ASP后台框架页:左边iframe套菜单树,右边iframe套功能页。这里值得注意的不是布局,而是它的鉴权方式。老代码里最常见的是Session判断后再渲染页面,比如首页里对管理员身份做一次检查:
<% If Session("admin") = "" Then Response.Redirect "login.asp" End If %>这段代码的逻辑是:如果Session里没有admin标记,直接重定向到登录页。问题在于它只做了存在性判断,没做等级判断,也就是说只要登录过,任何后台子页面都能访问。实际加固时,我一般会把管理员等级字段一并写进Session,例如Session("admin_level"),在每个功能页开头做大于等于阈值的校验,这样避免低权限账号直接访问Admin_Data.asp这类危险页面。
文件清单里还有AdminList.asp和AdminEdit.asp,这一对是典型的列表加编辑组合。AdminList.asp读数据表生成表格,AdminEdit.asp接收表单提交执行Update。这组文件有个隐含约定:所有操作都围绕同一个数据库连接串展开,连接串通常放在include文件里,但v2.0的源码文件里没列出单独的conn.asp,那么大概率是写死在每个页面的顶部了。
2.2 Upclass.asp里的父级分类递归
Upclass.asp,从命名看是上级分类管理,对应展厅里的一级展区。它做的事情是读取分类表中parentid为0的记录,再递归输出子分类。老ASP写递归不花哨,但逻辑值得看:
<% Sub ShowClass(parentId, level) Dim rs, sql sql = "SELECT * FROM class WHERE parentid=" & parentId & " ORDER BY orderid" Set rs = conn.Execute(sql) Do While Not rs.EOF For i = 1 To level Response.Write " " Next Response.Write "├─ " & rs("classname") & " (" & rs("id") & ")<br>" Call ShowClass(rs("id"), level + 1) rs.MoveNext Loop rs.Close End Sub %>这里的模型是邻接表,每行记录存parentid,层级靠递归算。展厅系统里展区分三级以内时性能没问题,但如果分类涨到几千条,递归查询会拖慢后台。升级思路是加一个path字段存完整路径,比如0,1,12,34,这样查询子分类直接Like即可,不用递归。
2.3 表格:这套后台文件的职责边界
| 文件 | 职责 | 涉及数据表 | 关键风险 |
|---|---|---|---|
| Admin_Index.asp | 后台框架与鉴权入口 | 无 | Session校验薄弱 |
| Upclass.asp | 展区分类树管理 | class | SQL拼接注入 |
| AdminList.asp / AdminEdit.asp | 展品内容增删改 | product | 更新时缺条件 |
| Admin_Pic.asp / Admin_PicEdit.asp | 图片上传与替换 | pic | 文件校验不足 |
| Admin_Data.asp | 数据库备份与恢复 | 全局 | 备份文件可被下载 |
这个表格说明一个问题:整套后台的文件名即功能名,分层很清楚,但所有页面都共享同一个风险,就是SQL拼接。后面第三章的NoSQL.Asp过滤,就是针对这个问题的老式解法。
3. Md5校验与NoSQL.Filter:旧时代的两道防线怎么改才靠谱
3.1 Md5.asp的算法实现和它的致命短板
Md5.asp是经典ASP的MD5算法封装,作用是把用户密码散列后存库。看这个文件时,重点不是算法本身,而是调用方式。v2.0里典型的登录校验长这样:
<% Dim pwdMd5 pwdMd5 = Md5(Trim(Request.Form("password"))) sql = "SELECT * FROM admin WHERE username='" & userName & "' AND pwd='" & pwdMd5 & "'" %>这个写法有两个隐患:第一,MD5无盐,同一个密码在不同账号下散列值相同,撞库直接命中;第二,密文直接参与SQL拼接,虽然Md5输出是十六进制字符不含单引号,但username那一段是没过滤的。常见做法是改成加盐再散列:Md5(username & "固定盐值" & password),并把盐值配置在独立文件中,避免源码泄露后直接被反推。
3.2 NoSQL.Asp不是NoSQL数据库,是防注入过滤器
这可能是v2.0里最容易被误解的文件。它的名字不是指NoSQL数据库,而是“No SQL Injection”,一个纯过滤脚本。老ASP项目里没有参数化查询,所有SQL都是字符串拼接,所以需要在入口对每个参数做处理,典型的代码是:
<% Function SafeStr(str) If IsNull(str) Then SafeStr = "" Exit Function End If SafeStr = Replace(str, "'", "''") SafeStr = Replace(SafeStr, ";", "") SafeStr = Replace(SafeStr, "--", "") End Function %>使用方式是在每个接收参数的位置调用,例如name = SafeStr(Request.Form("name"))。这个方案有一定防御效果,但只挡了单引号、分号和注释符,对宽字节注入、exec等攻击是无效的。如果保留老代码,我会在过滤函数里增加对exec|insert|select|delete|update|drop等关键字的正则检测,并且用ASP的Request.ServerVariables("HTTP_X_FORWARDED_FOR")做IP白名单限制后台访问。
3.3 兼容老代码的安全改造顺序
不要一上来就改数据库连接方式,老系统动大手术容易崩。我一般按三步走:
- 所有接收参数的地方统一过SafeStr,保留原函数名,内部实现换成数组黑名单过滤。
- 密码校验加盐,已存在的用户第一次登录时自动升级为新密文格式。
- Admin_Data.asp的备份文件放到Web目录之外,或者对bak文件加HTTP禁止访问规则。
改造完跑一遍原有流程,重点看展品图片上传和分类递归是否正常,因为这两块对参数格式最敏感,过滤规则太严可能导致编码被截断。
4. 图片上传与数据库备份:Admin_Pic和Admin_Data的实战细节
4.1 Admin_Pic.asp的上传与存储逻辑
Admin_Pic.asp是展厅图片管理页,负责上传展品图片。老系统通常用无组件上传或FileSystemObject手动接收二进制流。它的核心步骤是:读取上传文件流,判断扩展名,保存到upload目录,再把路径写入数据库。完整链路如下:
<% Dim savePath, fileName, fileExt savePath = Server.MapPath("/upload/") fileName = Request.Form("filename") fileExt = LCase(Mid(fileName, InStrRev(fileName, ".") + 1)) If Not (fileExt = "jpg" Or fileExt = "gif" Or fileExt = "png") Then Response.Write "仅支持 jpg/gif/png" Response.End End If ' 保存文件的代码省略,核心是生成随机文件名 %>这个校验只看扩展名,不看文件头。现在流行做法是读文件前几个字节判断真实类型,JPG的FF D8、PNG的89 50 4E 47,这样把木马伪装成图片的请求挡在门外。老系统没有这个能力也不要紧,至少要做到重命名文件和强制输出图片ContentType。
4.2 展厅图片的尺寸规范与缩略图问题
网上展厅系统的图片通常有两类用途:列表缩略图和展厅大图。Admin_Pic.asp如果只存原图,前端加载会非常慢。v2.0的处理往往是把缩略图生成交给代码,常见做法是用ASP的Jpeg组件,没有组件就直接存两份上传结果。实际维护中你会发现,老系统的upload目录里积压了大量没被引用的图,原因是删除展品时没同步删图。
4.3 表格:Admin_Data备份的文件级操作对照
| 操作 | 老式做法 | 问题 | 改进方案 |
|---|---|---|---|
| 备份 | File.Copy直接复制mdb | Access文件被占用导致复制失败 | 先停网站或锁库 |
| 恢复 | 上传mdb覆盖 | 覆盖时数据丢失 | 保留时间戳版本 |
| 下载 | 直接给路径 | 源码泄露风险 | 对bak目录加deny规则 |
Admin_Data.asp若实现的是数据库备份,底层就是文件复制,代码类似:
<% Dim fso, srcFile, dstFile Set fso = Server.CreateObject("Scripting.FileSystemObject") srcFile = Server.MapPath("data/bhweb.mdb") dstFile = Server.MapPath("backup/bhweb_" & Year(Date()) & Month(Date()) & Day(Date()) & ".mdb") fso.CopyFile srcFile, dstFile, True %>注意Access的Jet引擎写锁,备份时如果有用户正在提交表单,复制出来的文件可能损坏。建议代码在复制前先检测bhweb.mdb.lacc锁文件是否存在,存在就延迟重试,这在老教程里很少提到。
4.4 备份文件的下载防护
备份文件路径一旦被猜到,整个网站的数据就裸奔了。正确做法是给backup目录加web.config或IIS的请求筛选规则,禁止.mdb扩展名的HTTP访问。如果没有IIS控制权,可以把备份文件改名成.bak并放到upload目录之外,用ASP代码的Adodb.Stream按需输出,这样既保证可下载又避免直接暴露路径。
5. 3D展厅的切片视角与ManageLog日志定位法
5.1 展厅怎么在浏览器里形成3D感
这套系统的3D不是WebGL,而是切片视差:展厅地图被切成若干区块,每块作为独立div背景,通过JS控制分层的横向位移,制造出走进展厅的视觉错觉。每个展区对应一组图片,展品图挂到3D场景的特定坐标上。理解这一点对维护很重要,因为调“3D效果”不是改模型,而是改CSS的z-index和translateX偏移量。
5.2 新增展品时图片路径与页面配置要同步
我给这类系统加展品的常规顺序是:先在Upclass.asp里找到目标展区,记下分类ID;再到Admin_Pic.asp上传图片,获得图片ID;最后到Upclass.asp的绑定页面里把展品ID和分类ID关联。如果后台没有明确的关联入口,直接改数据库里product表的class_id字段。操作前备份数据表,这条路径我走过十几遍,最容易翻车的是漏了缩略图字段,导致列表页有图、展厅大图空白。
5.3 ManageLog.asp日志怎么用来排查故障
ManageLog.asp记录管理员的后台操作日志,排查上传失败和配置错误时非常有用。常见查询逻辑是登录后台-日志管理-按时间筛选,SQL类似:
SELECT * FROM manage_log WHERE action_type = 'upload' AND log_time >= #2025-01-01 00:00:00# ORDER BY log_time DESC关键看两栏:操作内容和IP地址。如果上传图片后前台不显示,日志里的记录能告诉你操作是否真的写入成功;如果日志里没有记录,问题大概率出在权限校验那一层。实际维护经验是,图片传上去了但展厅不刷新,80%是缓存问题,清浏览器缓存或者给图片URL加版本参数即可,剩下20%才是数据库字段没写对。
最后提一个小技巧:Admin_Pic.asp上传成功后返回的页面停留时间很短,不容易看清最终结果。调试时可以在保存代码后面临时加一行输出新图片的物理路径和数据库ID,确认无误后再删除,这比反复刷新列表页高效得多。
本文还有配套的精品资源,点击获取