二、在asp中执行
现在已经得出结论,rfc1867是在web应用程序上载文件的最好方式。那么如何来运行?microsoft提供了什么方法?其它有哪些方法可以用?
microsoft的posting acceptor
asp不支持multipart/form-data编码方式,但是,microsoft提供了免费的posting acceptor(http://www.microsoft.com/iis/support/iishelp/iis/htm/core/pareadme.htm),它是一个isapi应用程序,上载结束后,产生一个到asp页的重新投递。(见 scott stanfield的文章 issue of mind(98年七月))。
software artisans的sa-fileup
sa-fileup(http://www.softartisans.com/softartisans/saf.html)是最早的商业活动服务器组件(active server components)之一。第一版是97年5月开始使用的,现在全世界包括microsoft.com在内的上千个网站都在使用它。早期的beta版本用isapi过滤器和活动服务器组件的联合体与asp结合起来。接着,microsoft推出了asp 1.0b(asp.dll 1.15.14.0),提供了一种新方法:request.binaryread(二进制读请求)。二进制读方法使浏览器中的原始未加工数据可以被活动服务器组件使用。这样一来,sa-fileup就不再需要isapi过滤器,而作为一个asp组件存在了。
sa-fileup使用二进制读请求,而不是通过表单对象。这样是有意义的:你怎能一边从浏览器读原始数据流,又同时把它作为表信息来解析呢?为了照顾asp开发人员,sa-fileup 在它自己的表集里重新提供了所有的表请求 功能。这样使习惯于使用表请求的asp编程人员对sa-fileup 能够更加熟悉。
posting acceptor与sa-fileup 之比较
现在就pa和sa-fileup进行一个尽可能客观的比较:
■ 与asp的结合性:sa-fileup在asp中是完全可脚本化的,它可以与asp应用程序很好地结合起来, 而不是作为一个独立的isapi dll存在。
■ 标准支持性:从ie浏览器进行pa上载要使用其特有的webpost api,所以不如rfc1867, 使用pa,对于netscape和ie用户要使用不同的格式。
■ 匿名连接:由于pa使用一个isapi dll,在asp应用程序以外它就必须提供额外的安全保护。因此在默认状态下pa不允许一切匿名连接。pa 1.1可以允许匿名上载,但是因为有一个上载的编程控制,这里仍然有一定的危险。由于sa-fileup已经和asp结合在一起,应用程序可以决定适当的安全度,包括匿名。
■ 上载控制:上载正在发送时,pa不允许任何控制。但是用sa-fileup,可以限制上载的规模或实时决定取消上载。而最好的一点在于可以动态改变上载的位置。
■ 处理过程:pa有两步:上载和重新投递。用sa-fileup,一切都可以一步完成,例如根据上载的状态写数据库。
■ 上载到一个数据库:pa只能上载到文件,sa-fileup可上载到文件和数据库。
■ “文件名中的空格”:当处理含有空格的文件名时,pa存在问题;sa-fileup就没有这样的漏洞。
■ 价格:pa可从microsoft免费下载,与nt选项软择包捆绑在一起。而sa-fileup不是免费的:它是有支持的商业组件。
vertigo software的总裁scott stanfield(http://www.vertigosoftware.com/), 是mind杂志98年7月号上post accetpor文章的作者,mind上的文章发表之后,在 software artisans 上关于sa-fileup,他又写道:“知道了[sa-fileup]非常兴奋,这真是奇妙而有价值的产品。”
共同的支持问题
到现在为止,有关文件上载的支持问题主要是与安全有关的。通常网站都过分小心地保护ntfs 许可,它可以防止匿名用户帐号向文件目的地址中进行写入。而且即使是 高级服务器管理员也经常错误理解安全的含义。
要记住,iis/asp在一个特别的安全环境下运行每个asp页。如果没有鉴别机制(没有basic,没有nt challenge/response),每一页都作为匿名用户执行。网络管理员可以设置与匿名用户相应的nt帐号。
对于iis3,默认的匿名用户是iusr_< computername >。
对于iis4,所有运行中的网络应用程序的默认匿名用户都是iusr_< computername >(“在单独的内存空间运行”不被查看)。所有运行以外的应用程序的默认匿名用户是 iwam_< computername > (“在单独的内存空间运行”被查看)。
使用sa-fileup时,必须保证适当的用户对目的路径有读、写、删除许可。
如果鉴别功能发挥作用,在运行asp页的过程中iis/asp 就将扮演已经鉴别的用户。 因此经鉴别用户的注册帐号对目的路径必须有读、写、删除许可。
对iis安全的深入讨论已经超过了本文的范围,the iis 4 resource kit有很好的解释。
一些代码
理论已经足够了,下面来看一些asp代码。
单个文件上载
下面是单个文件上载的一个简单的html格式。
< html > < head > < title >please upload your file< /title >
< /head > < body > < form enctype="multipart/form-data" method="post" action="formresp.asp" >
enter filename to upload: < input type="file" name="f1" > < input type="submit" > < /form > < /body > < /html >
下面是文件formresp.asp:
< %@ language="vbscript" % >
< html >< head > < title >upload file results< /title > < /head >
< body > thank you for uploading your file.
< % set upl = server.createobject("softartisans.fileup") % >
< % upl.saveas "c: empupload.out" % >
total bytes written: < %=upl.totalbytes% >
< /body > < /html >
有附加表单元素的文件上载
增加附加表单元素非常简单。只要正确指定enctype,它就象任何普通html文件一样运行。
< html > < head > < title >please upload your file< /title >
< /head > < body >
< form enctype="multipart/form-data" method="post" action="mformresp.asp" >
enter description: < input type="text" name="descrip" > enter filename to upload: < input type="file" name="f1" > < input type="submit" > < /form >
< /body > < /html >
下面是文件mformresp.asp:
< %@ language="vbscript" % > < html >< head > < title >upload
file results< /title > < /head >
< body >
thank you for uploading your file. < % set upl = server.createobject("softartisans.fileup") % >
< % upl.saveas "c: empupload.out" % > your description is: < %=upl.form("descrip")% > total bytes written: < %=upl.totalbytes% >
< /body > < /html >
多文件上载
由于浏览器不支持size= 属性,对多文件的情况就必须在每个文件中都使用一个额外的< input >语句。
enter first filename: < input type="file" name="f1" > enter second filename: < input type="file" name="f2" >
格式处理是一样的:
< %@ language="vbscript" % > < html >< head >
< title >multiple file upload results< /title > < /head >
< body >
thank you for uploading your files. < % set upl = server.createobject("softartisans.fileup") % > < % upl.form("f1").saveas "c: empupload1.out" % > total bytes written for file 1: < %=upl.form("f1").totalbytes% > < % upl.form("f2").saveas "c: empupload2.out" % > total bytes written for file 2: < %=upl.form("f2").totalbytes% > < /body > < /html >
限制上载规模
要限制上载规模,只需要设置一个属性:
< %@ language="vbscript" % > < html >< head > < title >upload file results< /title > < /head > < body > thank you for uploading your file. < % set upl = server.createobject("softartisans.fileup") % > < % upl.maxbytes = 1000 — limit the upload size to 1000 bytes % > the maximum size that you are permitted to upload is < %=upl.maxbytes% > bytes per file. < % upl.saveas "c: empupload.out" % > total bytes written: < %=upl.totalbytes% > server filename: < %=upl.servername% > total bytes transmitted by you: < %=request.totalbytes% > < /body > < /html >
第1000个字节后的内容都将被删除,web服务器的磁盘就不会不必要地被占满。
结论
在web应用程序中实现上载文件非常简单:区区两行asp代码就能完成。http/rfc1867文件上载因服务器提供的丰富的编程环境成为首选。sa-fileup作为与asp结合的活动服务器组件,比microsoft的posting accetpro有明显优势。
