asp文件上传
用ASP做文件上传,很多人第一反应是去找第三方组件。十多年前我也这样,试过SA-FileUp、AspUpload,功能确实强,但授权费不便宜,小项目根本划不来。后来发现,IIS自带的Request.BinaryRead配上ADODB.Stream,不花一分钱也能跑通,关键是你得搞明白HTTP请求体到底长什么样。 浏览器提交带文件的表单时,Content-Type会变成multipart/form-data,后面跟一个boundary字符串。整个请求体被这个boundary切成若干块,每块对应一个表单字段。普通文本字段就是一段头信息加值,文件字段多了filename和Content-Type。ASP里用Request.BinaryRead把原始字节全部读进来,存成字节数组,然后自己写解析逻辑,按boundary切分,再从中提取文件名和文件内容。 直接上代码。先定义一个函数,把二进制数据转成字符串方便查找分隔符: 读请求体的时候要注意,Request.BinaryRead只能调用一次,而且必须先判断Request.TotalBytes。我见过有人先访问Request.Form再调BinaryRead,结果直接报错——IIS已经把数据解析过了,二进制流拿不到。所以上传页面的表单字段,除了文件本身,其他值也得从二进制流里自己抠出来,不能偷懒用Request.Form。 解析的核心是找到第一个boundary的位置,然后循环往后找下一个。每两个boundary之间就是一块数据。块的开头两行是Content-Disposition和Content-Type,空行之后才是真正的值。文件内容里可能包含任意字节,包括看起来像boundary的序列,所以匹配的时候要严格按“\r\n--boundary”来定位,不能只搜boundary字符串。 提取文件名有个坑:不同浏览器发过来的filename格式不一样。IE老版本会带完整路径,比如C:\Users\xxx\Desktop\photo.jpg,Chrome和Firefox只给文件名。得用InStrRev找最后一个反斜杠或斜杠,截取后面的部分。文件名里如果有中文,还得考虑编码问题——IE用GBK,Firefox用UTF-8,同一个页面两种浏览器上传,文件名可能一个正常一个乱码。我一般统一按UTF-8处理,IE那边加个判断,如果文件名里出现百分号编码就手动解码。 保存文件用ADODB.Stream最省事。把提取出来的二进制块写入新流,直接SaveToFile。路径要写服务器绝对路径,Server.MapPath一下。权限方面,IIS默认的IUSR账号对网站目录只有读权限,得手动给上传目录加写权限。很多人卡在这一步,代码没问题但文件死活存不进去,就是权限没配。 还有个细节:Request.BinaryRead读出来的数据,如果文件超过100KB,IIS默认会限制。得改metabase里的AspMaxRequestEntityAllowed,或者干脆在web.config里配maxRequestLength。不调这个,大文件上传直接500错误,连ASP代码都进不去。 这套方案我用了很多年,传个几兆的图片文档完全没问题。缺点也明显:纯ASP解析二进制,性能比组件差一截,并发高了CPU扛不住。但胜在零依赖,扔到任何支持ASP的空间都能跑。你要是做个内部小系统,或者帮人维护老站点,这招比装组件实在得多。Function BytesToString(bytes) Dim stream Set stream = Server.CreateObject("ADODB.Stream") stream.Type = 1 stream.Open stream.Write bytes stream.Position = 0 stream.Type = 2 stream.Charset = "iso-8859-1" BytesToString = stream.ReadText stream.Close Set stream = Nothing End Function
-
上一篇
-
下一篇
- 随机阅读
- 搜索
-
- 友情链接
-