高级 ASP 上传器






4.95/5 (16投票s)
2001年5月20日
3分钟阅读

459383

7559
一个提供文件上传功能的COM组件,用于你的ASP页面。
引言
基于浏览器的(HTTP)文件上传是实现将任意文件从客户端机器传输到Web服务器的一个绝佳方式,它为Web应用程序增加了另一个维度。然而,要启用此功能,客户端表单必须使用"multipart/form-data"编码进行提交。
不幸的是,ASP的Request.Form
对象无法用于这种编码类型(当前)。因此,许多第三方组件提供了解决方案来解决这个问题。然而,大多数第三方组件都存在以下一个或多个问题:
- 丢弃与上传文件无关的其他重要表单数据。
- 不支持多文件上传。
- 与现有Request.Form接口不一致。
- 不支持从上传的文件中读取块数据(在通过ADO
Recordset
对象的AppendChunk
将大文件上传到数据库的BLOB字段时非常有用)。
因此,我开发了一个COM对象,用户可以在"multipart/form-data"编码的情况下使用它来代替Request.Form
。
在开发这个COM对象的过程中,我试图避免上述任何问题。然而,我提供的解决方案并不能完全取代Request.Form
,而是一个补充解决方案,用户可以在前面提到的"multipart/form-data"编码时使用。当然,对于其他编码类型,用户仍然可以使用Request.Form
。
什么是multipart/form-data?
这种"multipart/form-data"编码类型在RFC1867中有描述,它说明了如何在HTTP协议上实现文件上传。要启用文件上传,表单的enctype应设置为multipart/form-data
,method应设置为post
。然后,input标签的type应为file
。

对于前面的表单,这是所需的代码:
<form method=post action=upload.asp enctype="multipart/form-data"> <input name=name value="Al-Mutairi, Fayez"> <input name=email value="fayezmm@yahoo.com"> <input name=file type=file> <input name=submit type=submit value=Submit> </form>
当用户点击提交按钮时,Web服务器将收到以下内容:
-----------------------------7d1f5a80420 Content-Disposition: form-data; name="name" Al-Mutairi, Fayez -----------------------------7d1f5a80420 Content-Disposition: form-data; name="email" fayezmm@yahoo.com -----------------------------7d1f5a80420 Content-Disposition: form-data; name="file"; filename="C:\folder_icon.gif" Content-Type: image/gif GIF89a2 2 ³ÿ ÿÿÿÌÌÿ™™ÿffÌUUUDDD33f""" , 2 2 @ éÈI«½8ëÍ»¯H Ž" … ,‹|]HÎ49 7ì!Å Ô³[NGÔ Ž‡CqÉl:‹¯Sê'@žfB©<¯§v †±ž φC$ „+zN¯Ûün$u§/z-Vvc@*<,{bdd UX†ŽlCb=?•#f|jš4fqŒžŸ=>fo¦®¯°±²³N G¬´Ÿ<_z³2ˆT„Á…\R_-ƒ¥µÆ+ƒs”‡ÍŠÃMÑŽ]*gÖ›5ÝAm“áâ—Ökå/ßh Ýìuî[£ò–npÊ…™" ª(úø¨ió/ ®ƒ*¬/ ; -----------------------------7d1f5a80420 Content-Disposition: form-data; name="submit" Submit -----------------------------7d1f5a80420--
此时,当upload.asp开始运行时,它无法使用Request.Form
访问表单数据,因此需要第三方组件的帮助。该组件将读取之前的请求,进行解析,并构建一个项集合,这些项可以以类似于访问Request.Form
项的方式进行访问。
如何使用该组件
让我们使用我们的MyRequest.Form
组件来构建upload.asp。
<%@ LANGUAGE="JScript%"> <% var form = Server.CreateObject("MyRequest.Form"); form.Init(); Response.Write("Name =" + form("name")); Response.Write("Email =" + form("email")); var file = form.Item("file").Item(1); Response.Write("FileName =" + file.FileName); Response.Write("FileExt =" + file.FileExt); Response.Write("FilePath =" + file.FilePath); Response.Write("MimeType =" + file.ContentType); Response.Write("FileSize =" + file.TotalBytes); // ** To save into a file use Write method of the ADO Stream Object var fileStream = Server.CreateObject("ADODB.Stream"); fileStream.Open(); fileStream.Type = adTypeBinary; fileStream.Write(file.Value); fileStream.SaveToFile(Server.MapPath("Uploaded Files") + "\\" + file.FileName, adSaveCreateOverWrite); fileStream.Close(); // ** To save into a database use AppendChunk method of the Field Object of ADO Recordset var cn = Server.CreateObject("ADODB.Connection"); var rs = Server.CreateObject("ADODB.Recordset"); cn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("Database.mdb")); rs.Open("Users", cn, adOpenForwardOnly, adLockOptimistic, adCmdTable); rs.AddNew(); rs.Fields("id") = 1000; rs.Fields("name") = form("name").Value; rs.Fields("email") = form("email").Value; rs.Fields("FileType") = file.ContentType; rs.Fields("file").AppendChunk(file.Value); rs.Update(); rs.Close(); %>
接口
这是 | |
方法 | 描述 |
Init(VARIANT varBinary) |
使用已提交的数据初始化表单。varBinary是可选的,等于Request.BinaryRead(Request.TotalBytes) 。 |
Item(VARIANT Index, IListItem** ppItem) |
(默认方法) 返回指定键的ListItem对象,该键可以是项的名称或索引。 |
Count(long* pVal) |
ListItem对象的数量。 |
这是 | |
方法 | 描述 |
Value(VARIANT* pValue) |
(默认方法) 项的值。 |
Item(long lIndex, IItem** ppItem) |
返回指定索引的Item对象。 |
Count(long* pVal) |
项的数量。 |
Name(BSTR* pName) |
项的名称。 |
这是 | |
方法 | 描述 |
Value(VARIANT* pValue) |
(默认方法) 返回项的值。 |
IsFile(BOOL *pVal) |
如果Item对象是一个文件,则返回TRUE,否则返回FALSE。 |
FileName(BSTR *pVal) |
上传文件的名称。仅当对象是文件时可用。 |
FilePath(BSTR *pVal) |
上传文件的路径。仅当对象是文件时可用。 |
FileExt(BSTR *pVal) |
上传文件的扩展名。仅当对象是文件时可用。 |
ContentType(BSTR *pVal) |
上传文件的内容类型(MIME TYPE)。仅当对象是文件时可用。 |
TotalBytes(long *pVal) |
上传文件的大小(以字节为单位)。仅当对象是文件时可用。 |
GetChunk(long offset, long length, VARIANT* pChunk) |
返回指定大小和位置的文件块。仅当对象是文件时可用。 |
进一步帮助
演示项目zip文件还提供了额外的帮助,其中包括文档!
特别感谢Xicoloko,他写了https://codeproject.org.cn/asp/uploader.asp,这给了我灵感,也构建了自己的组件,但这次是(完整的)。