网络广泛流传的一个asp上传类的一处BUG
申明要点:
1.该问题可能存在于版本比较旧的稻香老农的化境上传类中,主要错误是:截取上传分割字符误差导致可能漏掉最后一个表单项.其它方面不影响使用.
2.顺便提及一些无组件上传常见的问题.
起因:
群内的一个朋友不太熟悉asp,做文件上传功能的时候,想在选择文件后,不用点击上传按钮,表单就自动上传,我说,这个简单啊,放一个onchange事件就行了.
他说试过了,不自动的时候就能上传,改成自动,上传就空了.我说,那你输出下Request.totalBytes,看数据流是否正确.他试了下,也正确.由于当时也比较忙,而且我觉得,上传类应该没问题吧,就想可能是他哪里弄错了.就让他仔细检查代码.
结果到了下午,问题还是没能解决,没办法,让他把相关代码打包发我看,真不信活见鬼的事.
分析:
简单修改了代码,一测试,果然如此,于是在上传类解析表单项里添加了调试代码,发现实际解析的表单项比form中少了一个,问题就在于,他的上传按钮属于submit类型,又有name属性,所以,在点击上传按钮时,该按钮是属于最后一个表单元素,那么,漏掉它,文件自然是正常上传.而自动提交时该元素的值就不会被提交,文件成了最后一个表单元素,被漏掉了,自然上传文件为空,而且,也没有任何错误.
我又用我常用的无惧上传类v1.2测试,所有表单项均无误,点击上传按钮时,上传按钮的名称及值也能正确接收.
仔细比较了两个上传类的代码,发现解析表单的循环不一样,无惧上传类是采用一个起始点后移,直至+2时大于等于总长度.而那个上传类(可能被人修改,没留信息,怀疑是稻香老农或化境的旧版本,因为解析中使用了自定义的instring和substring函数,效率比较慢,后来很多上传类都没有用了,而是直接用instrB和instr,效率很快),是采用两点同时后移,判断后一点超出数据流末尾时结束,所以,起初怀疑是这里的问题,但修改了下,并没有起色,于是再住上面,将获取的分割字符输出,一比较,原来多了个回车换行符,这样,因为表单最后一个分割符是以--结尾,而没有换行符了,就导致无法匹配到最后一个分割符,而漏掉了最后一个表单元素.
修改:
知道了原因,修改就方便了,只要将分割字符处理正确,应该就没有问题了.起初我怀疑改了后,下面解析会有错位,结果没有问题.
将类初始化方法中大约往下十几行
iDivLen=inString(1,vbEnter)+1
修改为
iDivLen=inString(1,vbEnter)-1
是的,就一个符号.觉得自己的上传类有问题的朋友,不妨测试下表单项是否有遗漏,当然,不影响使用可以不用管,但版本最好还要升级一下,因为一些旧的上传类因为用了自定义的substring和instring方法,效率不是一般的差,一个3-4M的文件,要处理3秒多,而新版本,几乎零秒(我说几乎,是因为程序测试确实是0秒).
另外的问题:
很久之前在百度上回答了个关于upload_5x_soft类没有初始化的问题,从此便再无宁日,几乎每天都有朋友加我qq询问此问题.拒人于千里之外,不是我的风格,有问必答,每天都要浪费很多时间,而且问这个问题的,大多是初接触asp或外行人弄了个这样的程序来用,很不容易讲明白是怎么回事,怎么解决.虽然网上我曾经见过有比较完美的解答(好像在csdn或iteye上?),但这里我觉得有必要赘述一遍.
问题根源:
看人不能一棒子打死,问题也是如此,我只讲这个问题的最常见根源,就在于使用了netbox(有些人就把它当作是iis,怎么都讲不明白)之类的iis调试工具,而上传类中没有使用<%%>这种asp标签,而是使用了<script runat=server>的标签,这在netbox(及其类似软件)中是不能运行的,因此,upload_5x_soft这个类当然无法初始化.
其它问题也有如包含文件路径错误,或写的类名称不符等,就不多说了
解决方法:
1.最有效的方法,改用iis调试.(咱不讲wps,现在有电脑的,至少也是xp系统吧,可能有一部分老的,也应该是2000).或者有服务器的上传到服务器上调试(就我所知,没有空间商卖netbox host的空间吧).
2.也可以手动将上传类中的标签改成asp标签(怎么改?这个我真不知道),部分测试工具可能行不通,就不要钻牛角了.
本来昨天想写这个问题的,确实比较忙,所以,今天牺牲了仅有的一个周末,或许可以增加我以后的安宁吧.上帝保佑.