文件上传技术解析

文件上传是Web应用程序中一个非常实用的功能,它允许用户从客户端机器上传任意文件到Web服务器。为了实现这一功能,客户端的表单需要使用"multipart/form-data"编码方式提交。然而,ASP的Request.Form对象并不支持这种编码类型,因此需要第三方组件来解决这个问题。但是,这些第三方组件往往存在一些问题,比如丢弃与上传文件无关的其他重要表单数据,不支持多文件上传,与现有的Request.Form接口不一致,以及不支持从上传的文件中读取块数据(这对于将大文件上传到数据库的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,方法应该设置为post。然后,输入标签应该是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 [二进制文件内容] -----------------------------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接口的方法描述:

Method Description Init(VARIANT varBinary) Initialize the form with posted data. varBinary is optional it is = Request.BinaryRead(Request.TotalBytes) Item(VARIANT Index, IListItem** ppItem) (Default method) Returns the ListItem object with the specified key either as the item name or index. Count(long* pVal) Number of listitem's objects.

以下是IListItem接口的方法描述:

Method Description Value(VARIANT* pValue) (Default method) Item's value. Item(long lIndex, IItem** ppItem) Returns the Item object with the specified index. Count(long* pVal) Number of item's objects. Name(BSTR* pName) Item's name. Method Description Value(VARIANT* pValue) (Default method) Return the value of the item. IsFile(BOOL *pVal) Return TRUE if the Item object is a file otherwise it returns FALSE. FileName(BSTR *pVal) The name of the uploaded file. AVALIABLE ONLY if object is a file. FilePath(BSTR *pVal) The path of the uploaded file. AVALIABLE ONLY if object is a file. FileExt(BSTR *pVal) The extension of the uploaded file. AVALIABLE ONLY if object is a file. ContentType(BSTR *pVal) The content-type (MIME TYPE) of the uploaded file. AVALIABLE ONLY if object is a file. TotalBytes(long *pVal) Size in bytes of the uploaded file. AVALIABLE ONLY if object is a file. GetChunk(long offset, long length, VARIANT* pChunk) Return a chunk of the file with the specified size and position. AVALIABLE ONLY if object is a file.
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485