65.9K
CodeProject 正在变化。 阅读更多。
Home

高级 ASP 上传器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (16投票s)

2001年5月20日

3分钟阅读

viewsIcon

459383

downloadIcon

7559

一个提供文件上传功能的COM组件,用于你的ASP页面。

引言

基于浏览器的(HTTP)文件上传是实现将任意文件从客户端机器传输到Web服务器的一个绝佳方式,它为Web应用程序增加了另一个维度。然而,要启用此功能,客户端表单必须使用"multipart/form-data"编码进行提交。

不幸的是,ASP的Request.Form对象无法用于这种编码类型(当前)。因此,许多第三方组件提供了解决方案来解决这个问题。然而,大多数第三方组件都存在以下一个或多个问题:

  1. 丢弃与上传文件无关的其他重要表单数据。
  2. 不支持多文件上传。
  3. 与现有Request.Form接口不一致。
  4. 不支持从上传的文件中读取块数据(在通过ADORecordset对象的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();
%>

接口


这是IForm接口:

方法描述
Init(VARIANT varBinary) 使用已提交的数据初始化表单。varBinary是可选的,等于Request.BinaryRead(Request.TotalBytes)
Item(VARIANT Index, IListItem** ppItem) (默认方法) 返回指定键的ListItem对象,该键可以是项的名称或索引。
Count(long* pVal) ListItem对象的数量。

这是IListItem接口:

方法描述
Value(VARIANT* pValue) (默认方法) 项的值。
Item(long lIndex, IItem** ppItem) 返回指定索引的Item对象。
Count(long* pVal) 项的数量。
Name(BSTR* pName) 项的名称。

这是IItem接口:

方法描述
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,这给了我灵感,也构建了自己的组件,但这次是(完整的)。

© . All rights reserved.