asp上传文件源码
[探索] 时间:2026-10-17 04:25:54 来源:力不从心网 作者:焦点 点击:194次
ASP上传文件,传文说白了就是传文让用户把本地文件塞到服务器指定目录里。这事看着简单,传文真写起来坑不少。传文我见过太多人直接拿网上抄的传文代码,结果要么上传不了大文件,传文要么被黑客塞进个ASP木马,传文服务器直接变肉鸡。传文 先看最基础的传文写法。用ADODB.Stream对象,传文这是传文ASP里处理二进制数据的标准工具。伪代码长这样: ```asp <% Dim Upload,传文 FileData, FilePath Set Upload = Server.CreateObject("ADODB.Stream") Upload.Type = 1 '二进制模式 Upload.Open Upload.LoadFromFile Request.Form("file") '这行其实有问题,后面说 FilePath = Server.MapPath("uploads/") & "\" & Request.Form("filename") Upload.SaveToFile FilePath,传文 2 Upload.Close Set Upload = Nothing Response.Write "上传成功" %> ``` 这段代码看着能跑,但你拿它去应付真实项目,传文三天内必出事故。传文问题出在哪?`LoadFromFile`读的是服务器本地路径,不是客户端上传的文件。真正要处理的是`Request.BinaryRead`拿到的原始数据,那才是用户浏览器POST过来的内容。 正确姿势得自己解析二进制流。先设个表单,`enctype="multipart/form-data"`,然后ASP端用`Request.TotalBytes`拿数据总长,再`Request.BinaryRead`读进内存。接着得手工从这堆乱码里切出文件名、文件内容、分隔边界。这活儿烦人,但避不开。 我写过一版能用的,核心思路是找分隔符。浏览器发来的数据格式有规律:先有个`-----------------------------7dxxx`这样的边界串,后面跟`Content-Disposition`头,空一行,然后是文件二进制,直到下一个边界串。代码里用`InstrB`找字节位置,`MidB`截数据,最后`ADODB.Stream`写出。 给你看个关键片段: ```asp Dim FormData, DataStart, DataEnd, Boundary Boundary = "--" & Request.ServerVariables("HTTP_CONTENT_TYPE") Boundary = Mid(Boundary, InStr(Boundary, "boundary=") + 9) FormData = Request.BinaryRead(Request.TotalBytes) DataStart = InStrB(FormData, ChrB(13) & ChrB(10) & ChrB(13) & ChrB(10)) + 4 DataEnd = InStrB(DataStart, FormData, ChrB(13) & ChrB(10) & "--" & Boundary) - DataStart FileData = MidB(FormData, DataStart, DataEnd) ``` 这段能跑,但别急着庆祝。你还没处理文件名呢。文件名藏在`Content-Disposition`那行里,得用正则或者字符串搜索剥出来。而且得考虑中文文件名,浏览器编码不一样,搞不好存到服务器上就是乱码。我一般统一改成时间戳加随机数,省心。 安全性才是大头。上传目录权限设成只读,别给执行脚本的权限。IIS里把`uploads`文件夹的“脚本资源访问”勾掉。文件类型白名单,别黑名单——黑名单永远漏。`.asp`、`.aspx`、`.cer`、`.asa`这些直接拒。还得检查文件头,比如图片的`FF D8 FF`,别信扩展名。我见过有人传个`shell.jpg`,里面全是ASP代码,IIS配了通配符映射就完蛋。 有个真实案例。2019年我帮朋友排查一个被黑的站点,对方就是通过上传漏洞搞的。上传页面没过滤,直接`SaveToFile`到web根目录。攻击者传了个`cmd.asp`,整个服务器跟裸奔似的。后来我给他加了层校验:先读前几百字节,判断是不是合法图片,再重命名文件,最后把上传目录挪到web根之外,用虚拟目录映射。这才堵住。 性能也别忽略。大文件上传,比如几百MB的视频,`Request.BinaryRead`会把整个文件读进内存,服务器直接爆内存。解决办法是分块读取,边读边写临时文件。ASP里没现成的分块API,得自己循环`Request.BinaryRead`指定长度。麻烦是麻烦,但能救服务器一命。 最后说个容易忽略的点:`Server.MapPath`路径里的反斜杠。Windows下没问题,Linux的Mono环境就得用正斜杠。写代码时用`Path.Combine`逻辑自己拼,别硬编码。 上传文件功能写完,记得测几种情况:空文件、超长文件名、带特殊字符的文件名、并发上传。我吃过亏,并发时临时文件互相覆盖,数据全乱。后来每个请求生成唯一GUID做临时文件名,才算消停。 ASP老归老,但存量系统还在跑。你要是维护老代码,这几点够用了。别迷信网上那些“万能上传类”,自己动手拆一遍协议,比啥都强。
(责任编辑:探索)
相关内容
